Any advice on printing to a printer?

I have several screens of data where users are now requesting that I offer printing (league leaders, game stats, game drives, etc). I’d also like to be able to save them to disk, so I guess this is two questions.

Oh, and I definitely want to support desktop on this, both Mac and Windows.

First, any advice on bringing up the Windows/Mac printer selection so they can print?

Second, I’ve never found a good way to bring up Explorer (or Finder) in order to save files to user’s selected locations. Any suggestions?

thanks,
Kerry

Printing is surely a platform native api. You could also bundle cups and look for printers and make your own printer dialing. It can find windows printers too. This could have a few interesting benefits.

For explorer I would surely write your own quickly because you can only show specific files in it and there isn’t a way to use modifier keys to show any other files like you can in the OS. There is also platform native ways to do this and set limits too.

I wrote a cross platform GUI toolkit a long time ago. I’d be happy to share it on GitHub as an educational experience.

Thanks, I’ll look up cups, and I’m going to check out tiny files dialog, too. This is all mainly for Windows (and hopefully Mac). I don’t think it’s as necessary on iOS (no iPhone users have requested it), so I may even see if I can find an easy way to bring up a Windows print dialog in the short term.

Actually, now that I think about it, it’s probably much more important that the user be able to save these to files, because then they can print them at their leisure. So it would make more sense to have a Windows file system browser (and Mac, if possible).

Your toolkit sounds nice! I’d love to see it.

Well i will suggest you the same for your problem.
Prompt windows system browser to ask user where he/she wants to save image and save image over there via render-texture or saveImage.
I had made Level-maker for my own game so for that i had added few options like New, Open, Save for project files and for saving level data into binary etc.
For that you can use ShellExecute & IFileOpenDialog, you can google it for more info, it wont be that hard to find code for that.
If you have still problem let me know, i will share mine.
Edit:
I had no clue for Mac.

1 Like

This is Win32 file dialog code that I’ve used before (original source), updated with Cocos2d-x logging:

        char filename[MAX_PATH];

        OPENFILENAMEA ofn;
        ZeroMemory(&filename, sizeof(filename));
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = NULL;  // If you have a window to center over, put its HANDLE here
        ofn.lpstrFilter = "Text Files\0*.txt\0Any File\0*.*\0";
        ofn.lpstrFile = filename;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrTitle = "Select a File";
        ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;

        if (GetOpenFileNameA(&ofn))
        {
            CCLOG("You chose the file %s",  filename);
        }
        else
        {
          // All this stuff below is to tell you exactly how you messed up above. 
          // Once you've got that fixed, you can often (not always!) reduce it to a 'user cancelled' assumption.
            switch (CommDlgExtendedError())
            {
            case CDERR_DIALOGFAILURE: CCLOG("CDERR_DIALOGFAILURE");   break;
            case CDERR_FINDRESFAILURE: CCLOG("CDERR_FINDRESFAILURE");  break;
            case CDERR_INITIALIZATION: CCLOG("CDERR_INITIALIZATION");  break;
            case CDERR_LOADRESFAILURE: CCLOG("CDERR_LOADRESFAILURE");  break;
            case CDERR_LOADSTRFAILURE: CCLOG("CDERR_LOADSTRFAILURE");  break;
            case CDERR_LOCKRESFAILURE: CCLOG("CDERR_LOCKRESFAILURE");  break;
            case CDERR_MEMALLOCFAILURE: CCLOG("CDERR_MEMALLOCFAILURE"); break;
            case CDERR_MEMLOCKFAILURE: CCLOG("CDERR_MEMLOCKFAILURE");  break;
            case CDERR_NOHINSTANCE: CCLOG("CDERR_NOHINSTANCE");     break;
            case CDERR_NOHOOK: CCLOG("CDERR_NOHOOK");          break;
            case CDERR_NOTEMPLATE: CCLOG("CDERR_NOTEMPLATE");      break;
            case CDERR_STRUCTSIZE: CCLOG("CDERR_STRUCTSIZE");      break;
            case FNERR_BUFFERTOOSMALL: CCLOG("FNERR_BUFFERTOOSMALL");  break;
            case FNERR_INVALIDFILENAME: CCLOG("FNERR_INVALIDFILENAME"); break;
            case FNERR_SUBCLASSFAILURE: CCLOG("FNERR_SUBCLASSFAILURE"); break;
            default: CCLOG("You cancelled.");
            }
        }

A few things to note though: If you need UNICODE support then OPENFILENAMEA needs to change to OPENFILENAME (or OPENFILENAMEW, but when the UNICODE preprocessor define exists, which is the case with Cocos2d-x, OPENFILENAME = OPENFILENAMEW). If you do use that, then char would need to change to CHAR or wchar_t, and as a result, you would need to convert the result stored in filename to char before using it with certain functions in Cocos2d-x.

1 Like

Awesome, thank you! I don’t need unicode, so I’ll try this this weekend. Thanks!

Maybe is better to draw into pdf, instead of direct print?

1 Like

That would be great, but I don’t know how. Do you have suggestions on that? I’d like to be able to write to pdf and also to csv, because several of these screens are just a lot of data that people want to be able to pull into Excel or into their web sites.

I think that saving to disk would be better than printing. I’ll try R101’s idea this weekend, but I see it requires me linking with some lib I don’t have, so I’ll have to find out more about that.

I think http://libharu.sourceforge.net/index.html is a good place to start, with full sorce code and bunch of examples. Other libs are:
http://podofo.sourceforge.net/
http://www.jagpdf.org/

2 Likes

In addition to what hexerror linked, you could try these options if you want to visually design your reports:

http://www.oxetta.com/report/doc/start.html

http://limereport.ru/en/index.php

Read up on the licensing terms for each of them, since there are a few restrictions.

Both of those report engines support data from a database connection or application defined data models.

1 Like

Writing csv is very easy as it’s text format

1 Like

Great ideas. Perhaps we could add these links to our FAQ I started.

https://docs.cocos2d-x.org/cocos2d-x/en/faq/

1 Like

Thanks, all! I currently export leagues to csv, but they’re in the default folder, which is under appdata/local/psf2020 on the PC and Documents/psf2020 on the Mac. If I could even find a way to write the Windows files to MyDocuments/psf2020, that would be a HUGE improvement. Does anyone know if there’s a way to do that?

Thanks again, everyone!

Try SHGetKnownFolderPath, with the ID of the folder you’re after, which in your case would be FOLDERID_Documents.

More info here and here.

1 Like

Oh my gosh, thank you SO much! I’ll look at that when I get home. That would be fantastic!

Oh my gosh, I just now had a chance to test your code for opening a Windows dialog, and I’m thrilled to say that it works! I need to read on it some more now to find out how to

  1. work in opening and saving (primarily saving, by far!)
  2. pre-set the name
  3. pre-set the file type to search (and limit it to those types)

UPDATE: some of that information is here if anyone needs it.

But this is great! Thanks! For completeness, I’m going to check other suggestions here, but thank you SO much!

Windows is more important than Mac, but later I’ll see if I can implement something similar with Finder. And last would be iOS. Thanks again!

-Kerry

This works great! Thanks!

I did get IFileDialog to work as well, and honestly, I prefer the older approach, so thanks again.

I’m glad you found the info useful. One thing to keep in mind is compatibility between different versions of Windows, so just check that those functions actually exist and have the same behavior with whichever version of Windows you’ll be supporting. You usually won’t run into any issues, but there have been incompatibilities in the past with certain Win32 APIs; perhaps undocumented functions that people used when they shouldn’t have, but I can’t remember at the moment.

Ok, thanks, I sure hope so. I’m supporting Windows 7, 10, and above, and should be supporting 32 bit and 64 bit. I don’t do anything different. It’ll be curious to see how this all works. That’s one reason I tried out the IFileDialog, and if I get time, I’ll try it again, just because it is more modern. Thanks again!