what parameter of PrintWindow should be used? - visual-c++

for some reason, I need to capture the screen of one application automatically, and I find one good example from link
How to get screenshot of a window as bitmap object in C++?
During my test, I found a strange thing (my test is based on Windows 10 with Visual C++ 2008):
in application of Windows notepad, I have to use parameter WM_PRINTCLIENT, or the captured is all black
PrintWindow(hwnd, hdc, WM_PRINTCLIENT);
in application that I want to capture, I have to use PW_CLIENTONLY, or the captured is all black
PrintWindow(hwnd, hdc, PW_CLIENTONLY);
So my question is that: what's the difference between them, and is there any rules? I tried to searching it in Internet but didn't find good hint.

Related

MBCS File Menus generate ???? Characters

I am working on an MBCS app using MFC. I am trying to support Asian languages. For the purposes of this discussion, we'll say I'm trying to support Chinese. I am able to support Pop up dialogs via MessageBoxW and Dialog SCREENs by pasting Chinese characters directly into the RC file. I can't get file menus to work using either resource view or editing the RC file directly. Whenever I type in ANY Asian character, the screen shows ???. One ? for each character. I have tried modifying the menu in C++ using ModifyMenuW. I get more question marks. Visual Studio shows everything working, and the RC file is unicode (UTF-16). I can't easily convert my project to unicode mode. Spanish, French, and German all works fine (one of the Essets in German doesn't work, but that isn't a show stopper). What should I try next?
Thanks in advance!
Well, the easy answer would be change the application to Unicode, but this is not always simple, or possible at all.
Concerning using Unicode in a MBCS application, some things are possible and some others not. For example, I have made a MBCS application displaying and editing translations of program strings (messages, menues etc) in a ListView control, however ListView does have a specific message to turn it to Unicode (LVM_SETUNICODEFORMAT) and support operations (see also CCM_SETUNICODEFORMAT). Menus aren't controls though, but they do have "wide" (Unicode) functions.
If you want to use Unicode in your application, there are some tests you need to make. Success is not guaranteeded, but you can at least draw some conclusions and determine whether what you want to do is possible.
Test1:
You mentioned trying ModifyMenuW(), but this will try to modify an existing menu. Instead, try InsertMenuW() or InsertMenuItemW(). Any unicode string should be displayed properly, so try not just Chinese, but other laguages too (eg Greek or Russian). And btw, I can't see how French works and German doesn't (they use the same codepage - West European). What's the system codepage of your test-machine?
Test2: (if the above has failed)
Try changing the whole menu (SetMenu()) with having a single (unicode) menu item as its root.
Test3: (if the above have failed)
Then you need to check whether the window containing the menu must be Unicode. Create a simple "Hello World" Win32 application, or find a sample, if Visual Studio does not do this for you (these basically register the window class, create the main window and start the message-loop) - you must add a menu too, using the "wide" version of the menu functions explicitly. If this doesn't work, try changing the code that creates the window to unicode. This way you will know whether you need a unicode window, to own the menu.
Please make these tests and let us know the results. I will further post if needed.

Embedded Qt Mouse Pointer Not Showing Up

I've got a bit of an interesting problem here. There are plenty of threads I've found where people are working to hide or get rid of a cursor on an embedded Qt GUI...but I'm trying to get a cursor to show up on an embedded Qt GUI.
I inherited a project that was 'finished' some time ago, and the person who did the most work on the project has moved on. Fast forward to today and there is a need to add a cursor to this functional touchscreen GUI. The system OS is Yocto Linux, and it is running a Qt 5.4 application on a framebuffer.
I've scoured the Qt code and there is nothing there that would hide a cursor. I've added in the appropriate QT_QPA_FB_HIDECURSOR=0 environment variable to my Qt startup script. I've experimented with adding a QCursor obejct to the GUI. Unfortunately none of these things are working. Using the QCusor I am sometimes able to get a cursor up on the screen, but isn't tied to the touch input (the cursor shows up at the position I programatically move it to, but it stays there when I interact with the GUI).
My touch input events are tied into Qt (via QT_QPA_GENERIC_PLUGINS=evdevtouch and QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event9:rotate=180), but for some reason that touch input cannot be tied to a cursor.
At this point I've spent a few days messing around with environment variables and startup script modifications, but nothing I've done has got the result I'm looking for.
Does anybody out there have some ideas on where to look for solutions to this problem?
Thanks!
Ian
So, now 3 months later I think my team and I just came up with a passable solution to this problem.
The path towards the solution started with the Qt Documentation on "Using libinput". The documentation boils down to a few important statements:
Parameters like the device node name can be set in the environment variables QT_QPA_EVDEV_MOUSE_PARAMETERS, QT_QPA_EVDEV_KEYBOARD_PARAMETERS and QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS
The mouse cursor shows up whenever QT_QPA_EGLFS_HIDECURSOR (for eglfs) or QT_QPA_FB_HIDECURSOR (for linuxfb) is not set and Qt's libudev-based device discovery reports that at least one mouse is available. When libudev support is not present, the mouse cursor always show up unless explicitly disabled via the environment variable.
The evdevtablet plugin provides basic support for Wacom and similar, pen-based tablets. It generates QTabletEvent events only. To enable it, pass QT_QPA_GENERIC_PLUGINS=evdevtablet in the environment or, alternatively, pass -plugin evdevtablet argument on the command-line. The plugin can take a device node parameter, for example QT_QPA_GENERIC_PLUGINS=evdevtablet:/dev/event1, in case the Qt's automatic device discovery (based either on libudev or a walkthrough of /dev/input/event*) is not functional or misbehaving.
So, in my system I have the device nodes: event0, event1, event2, event3, event4, event5, mice, and mouse0. Because I'm trying to get the mouse working, I made the assumption that I'd have to use the mouse0 node. This lead to me setting these environment variables:
QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/mouse0
Much to my frustration these environment variables led to nothing. After some time my team and I figured out how to get debug output from Qt source on our system:
Modifying source code in the qtbase directory under our yocto build (roughly /yocto/poky/build/tmp/work/temp build directory/qtbase
Copying qtbase/plugins/generic/libqevdevmouseplugin.so to my hardware (roughly /usr/lib/qt5/plugins/generic)
Running Qt from the command line
We quickly discovered that the input events coming from mouse0 and mice were basically garbage data. On our system we did set up EVDEV in the kernel, so the mouse input was also tied to the device node event0. When we tried setting the Qt mouse parameter to event0 we started to see debug output that looked like real data.
QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/event0
However, the problem of no-mouse-pointer still remained. After a while we looked back at the Qt Documentation, specifically at the 2nd paragraph listed above. As a last ditch attempt we tried adding in the QT_QPA_FB_HIDECURSOR environment variable...
QT_QPA_GENERIC_PLUGINS=evdevmouse
QT_QPA_EVDEV_MOUSE_PARAMETERS=/dev/input/event0
QT_QPA_FB_HIDECURSOR=0
And...voila! After countless hours of debugging and reading documentation, we finally got a mouse pointer.
I think the main crux of our issue was misinterpreting the Qt Documentation.
The mouse cursor shows up whenever ... QT_QPA_FB_HIDECURSOR (for linuxfb) is not set
By "not set", Qt means explicitly defined as FALSE...not simply "not set" at all.
This solution will work for us, but it does leave at least one thing to be desired. Along the way I stumbled across this thread answer on the Unix StackEx which points to the Kernel documentation of input/input.txt. In section "3.2.2 mousedev" you can see the line:
Each 'mouse' device is assigned to a single mouse or digitizer, except
the last one - 'mice'. This single character device is shared by all
mice and digitizers, and even if none are connected, the device is
present. This is useful for hotplugging USB mice, so that programs
can open the device even when no mice are present.
What this means for us is that while we can use event0 (which goes away when we unplug the mouse) for our mouse input event handling, we won't be able to support hot plugging without making some kernel/Qt-source modifications or figuring out how to get mice working as a Qt mouse input parameter.
So, the question of "why does event0 work and not mouse0/mice" still stands...but for now we've got a solution we can live with.
UPDATE: Now a little bit later we've figured out that udev was not working properly on our system. We added udev to the RDEPENDS in our package group for the Yocto build, and now we can set
QT_QPA_GENERIC_PLUGINS=evdevmouse
and we get a working mouse pointer with hotplug support.
I dont know if this applies to your problem (i dont use QT), but there is a
HAVE_TOUCHSCREEN=1 variable in the machconfig file. It is located normally in your BSP-layer in a recipes-bsp/formfactor/formfactor directory.
Setting this to 1 makes the cursor invisible.
Try setting it to 0

Entering text in Windows 8 in C#/MonoGame app

I'm writing a WinRT game for Windows 8, in C#, using the excellent MonoGame. I've reached the part where the user has achieved a high score and needs to enter their name. This is causing me more pain than I'd anticipated so I thought I'd ask for help.
First of all, is there a simple "enter some text" function that I can call, similar to Guide.BeginShowKeyboardInput in Windows Phone 7, or the ancient InputBox command in VB? I'm using Windows.UI.Popups.MessageDialog for displaying simple dialog messages, but can't find any similar thing for requesting text from the user.
Failing that, is there a way I can easily use a little piece of XAML to present a textbox for the user to use?
If neither of these are possible, I guess I'll have to wire this all up myself... I then would plan to intercept keystrokes and display the required text on screen myself. As I don't have a physical tablet (just the simulator) I'm struggling to start with this. How can I:
Detect whether the device has a physical keyboard, so I know whether or not to display the on screen keyboard?
If there is no physical keyboard, how can I show and hide the on screen keyboard?
Some of these sound like they should be easy to answer, but I've yet to track down answers to any of them.
Many thanks!
Adam.
Hey there is such a way to do this in monogame. There is a new template that allows you to create a XAML + Game game which allows you to use the game class you a used to with the xaml bits as well. These links should get you started. The monogame team rocks.
There are the three game types listed there. You want XAML + Game there is a template for it now if you get the proper version of monogame.
https://github.com/mono/MonoGame/wiki/Windows-8-Project-Types
let me know if you need more help
This is not a cross platform solution but you could use a FlyOut and place the controls for data entry on the window. FlyOut guidelines are here and UI Controls for text input guidelines are here. I have also used MessageDialog in a MonoGame for asking the user simple questions (up to 3 options) or to get a Yes|No response. You can get details of that class here.

Customizing/Replacing the Windows CE 5.0 Taskbar?

I'm currently getting my feet wet with Win CE 5.0 to update some code on an existing platform. We're interested in deploying a custom shell/home screen/application launcher as well and I had a couple questions:
1) We're running the standard CE shell and I'm assuming it can be customized because the source code is made available with Platform Builder. I was wondering how "painful" it would be to completely replace it with something like a status bar at the top of the screen (think iPhone). I was thinking task switching could then be handled by shortcut keys exclusively. I have my doubts about this.
2) If it can't be removed, can the taskbar be resized and moved to the top of the screen? We're basically trying to find a way to reserve the first 20 or so pixel rows at the top of the screen for our own status bar and prevent maximized application windows from drawing over top of it.
Thanks very much for the help.
-ksudeadeye
I was happy and angry when I found the solution because it's more easy than I expect.
For 2) reserve space you need to do this:
RECT rc;
SetRect(&rc, 0, 25, GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
SystemParametersInfoW(SPI_SETWORKAREA, 0, (void*) &rc, SPIF_SENDCHANGE);
With this code you reserve 25 pixels in the top of the screen.
:D
If you have doubts maybe this can help you or this.
Good luck.
To hide the task bar is a simple registry change:
; Hide the windows tasbar by default.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shell\AutoHide]
""=dword:1
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shell\OnTop]
""=dword:0
As far as customizing, your own, that is a little more work, and not something I've attempted.
I have some experience with modifying the taskbar in CE 5.0. It is not an easy task, but the results can really add that personal touch to the device. I was tasked with adding a user mode second taskbar with a password dialog and a second type of shell notification to add icons to the user bar.
In the end, it is just standard Windows CE programming - the taskbar, notification tray, start button, etc. are just like any other windows in the CE environment.
You should start exploring here:
C:\WINCE500\PUBLIC\SHELL\OAK\HPC\EXPLORER\TASKBAR\taskbar.cpp
Be careful, clone your code, and be prepared for lots of debug cycles. This is more than 5000 lines of serious spaghetti code.

Screen capture doesn't work on MFC application in Vista

We've got some in-house applications built in MFC, with OpenGL drawing routines. They all use the same code to draw on the screen and either print the screen or save it to a JPEG file. Everything's been working fine in Windows XP, and I need to find a way to make them work on Vista.
In three of our applications, everything works. In the remaining one, I can get the window border, title bar, menus, and task bar, but the interior never shows up. As I said, these applications use the exact same code to write to the screen and capture the window image, and the only difference I see that looks like it might be relevant is that the problem application uses the MFC multiple document interface, while the ones that work use the single document interface.
Either the answer isn't on the net, or I'm worse at Googling than I thought. I asked on the MSDN forums, and the only practical suggestion I got was to use GDI+ rather than GDI, and that did nothing different. I have tried different things with every part of the code that captures and prints or save, given a pointer to the window, so apparently it's a matter of the window itself. I haven't rebuilt the offending application using SDI yet, and I really don't have any other ideas.
Has anybody seen anything like this?
What I've got is four applications. They use a lot of common code, and share the actual .h and .cpp files, so I know the drawing and screen capture code is identical.
There is a WindowtoDIB() routine that takes a *pWnd, and a source rectangle and destination size. It looks like very slightly adapted Microsoft code, and I've found other functions in this file on the Microsoft website. Of my four applications, three handle this just fine, but one doesn't. The most obvious difference is that the problem one is MDI.
It looks to me like the *pWnd is the problem. I'm not a MFC guru by a long shot, and it seems to me that the problem may be that we've got one window setup in the SDIs, and more than one in the MDI. I may be passing the wrong *pWnd to the function.
In the meantime, it has started working properly on the 64-bit Vista test machine, although it still doesn't work on the 32-bit Vista machine. I have no idea why. I haven't changed anything since the last tests, and I didn't think anybody else had. (On the 32-bit version, the Print Screen key works as expected, but it does not save the screen as a JPEG.)
Your question title mentions screen capture but your actual question doesn't. Please elaborate more clearly. Is the problem that you can do screen capture of three of your applications, but not the fourth one? You can use different screen capture software that can capture OpenGL/DirectX windows. Those surfaces are handled directly by the Window Manager and won't show up with a simple 'PrtScn'.
Switching to GDI+ won't solve it, nor will switching to SDI.
If it's the content of the CView that you want, then yes, that should be right one. If it's the content of the whole screen (at least the content, without the toolbar(s) and status bar), then you should pass it the CMainFrame (that's the default name which may have been changed, the one that is derived from CMDIFrameWnd).
Can you post the code of WindowToDIB()? I've just tried it and It Works For Me (TM), but without OpenGL code in the view. Try passing the following windows to your WindowToDIB() function:
CMainFrame* mainfrm = static_cast<CMainFrame*>(::AfxGetMainWnd());
- mainfrm
- mainfrm->MDIGetActive()
- mainfrm->MDIGetActive()->GetActiveView()
and see what you get.
The contents of each window are directX surfaces and are only assembled by the window manager in the graphics card. You'd not be able to capture this unless you switch off the new interface (DWM) or code specifically for screen capture from the DWM.
Wikipedia has a good description of the Desktop Window Manager (DWM)
Sorry, I still don't understand. You're trying to get the Print Screen key to work on all four applications? Or you're trying to get the WindowtoDIB() function to work, which takes a 'screenshot' (from within your own application) of the application itself, so that it can be saved as an image file?
Also, what do you mean with 'he Print Screen key works as expected, but it does not save the screen as a JPEG.'? Print Screen only copies to the clipboard, what happens when you paste in Paint?
If your WindowtoDIB() function only 'captures' the window you pass to it, then yes, your MDI child windows are not going to show up.
We eventually solved this by creating a different OpenGL context, and drawing everything to that. We gave up on the screen capture.

Resources