I have created a simple game using Win32 and gdi. I would like to have a track bar at the bottom that tracks a global variable. I'm just not sure how to add controls. How could I add a trackbar? I can imagine it would get created in the wm_create event.
Do you mean TrackBar or StatusBar?
A StatusBar is normally located at the bottom of a window and displays informational messages about the application status, a TrackBar allows the user to select a value. Do you want to allow the user to select the value of your global variable or do you just want to display the current value of the variable? (I'm not sure if the trackbar will display the current value of the variable without extra work.)
Either way, there are samples for both StatusBar and TrackBar located on MSDN.
The child windows are normally created either in the WM_CREATE of the parent or after the parent window has been created (i.e. when you obtain a valid hWnd for the parent) and after calling InitCommonControls() and/or initializing COM if needed.
To create controls on the fly, in general use the CreateWindow function. With a bit of googling for "TrackBar+CreateWindow" you'll find a number of samples for your question:
i.e.:
http://zetcode.com/gui/winapi/controlsII/
or
http://msdn.microsoft.com/en-us/library/bb760151%28VS.85%29.aspx
Related
I'm using and improving on an open source MFC work-alike library called FFC. Sometimes the library associates the wrong window handle to a dialog object, which means the C++ object can't be found later when the correct handle is looked up. In particular, this is happening when the application opens its root window, which is a dialog that it opens with a call to DoModal.
In its DoModal function, the FFC library uses a... "surprising" way to attach the handle to the dialog object. It stashes the "this" pointer in a global variable and hooks a function to be called on all window messages before calling the DialogBox function. This hook function it registered in term assumes the handle from the first message it receives is the handle for the window in the global variable, and attaches that handle to it.
Sometimes, this works. Often - and I don't know if it's because of intrusive things done by the McAfee scanner on my work computer, or because my program starts from a console window, or something else - many unrelated messages will be captured before a message actually meant for the modal dialog comes through.
At first I thought it was because FFC wasn't making sure the message it looks for is "WM_CREATE". I added this check, but it didn't fix the problem. Turns out one or more of the spurious messages are also WM_CREATE messages! Before it gets the one for the real dialog, the first WM_CREATE it receives is a handle for a window with blank window text and rectangle 0,0-0,0.
So is this really the correct or canonical way to get the handle for a modal dialog? It seems unreliable. (Note that because the dialog is modal, you can't use the return value from CreateWindowEx because the DialogBox function doesn't return until the modal dialog is closed.) Is this really how MFC does it? Is there a better way? Could I associate some data with the dialog or look for data that should be associated with it to make sure I have the right window handle? (For instance checking the template parameter passed to the dialog box call, if I can get that back from the handle somehow.)
I am sure this is published in books, but MFC sets a windows hook (WH_CBT) and then looks for the HCBT_CREATEWND code in the hook to marry the C++ object to the HWND.
I'm hooking the QPainter::drawText() function of a Qt5 application on Windows.
My goal is to identify the native handle of the top-level-window to which the text is painted. First, I'm getting the associated widget.
QWidget *widget = static_cast<QWidget *>(painter->device());
So it should be possible to find the corresponding top-level window/widget.
But it's harder than I thought. This is what I tried so far:
while (widget->parentWidget())
widget = widget->parentWidget();
HWND hwnd = (HWND) widget->winId();
No success. The top-parent is never the desired window.
QApplication::topLevelWidgets()
Showed me that one single window contains several top-level-widgets (including the one I'm looking for).
I also tried QApplication::topLevelAt(widget->mapToGlobal(QPoint()))
In some cases this actually works, but not reliably.
Depending on text and window position I'm getting a AccessViolationException,
so this is not an option.
By testing widget->testAttribute(Qt::WA_NativeWindow)
I found out that most of the widgets are non-native Alien Widgets.
This is how I get the (what I call) top-level window.
WinAPI.EnumChildWindows(
WinAPI.GetDesktopWindow(),
new EnumWindowsProc(this.EnumWindowsCallback), 0);
Then I check the window titles to find the handles I'm interested in.
I'm not able to find a relation from any (low-level) widget to the (top-level) widget that holds the window title.
For the QWidget that acts as a top level window, call QWidget::window().
For the nearest parent with a native handle, call QWidget::nativeParentWidget().
Calling winId() forces the widget to acquire a native window handle if it does not have one, which isn't your goal. A top level window will always have a native id, so (HWND)window()->winId() is fine. Note that this is usually the same as calling QWidget::effectiveWinId().
It's done! I found a solution for my problem.
Each windows has it's own thread.
int threadId = WinApi.GetWindowThreadProcessId(wndHandle, IntPtr.Zero)
With it I use EnumThreadWindows
to get a list of all window-handles created by this thread.
Finally I check wheather widget->effectiveWinId() is in the list.
So I can map each widget to its corresponding window!
I'm writing a keylogger type application, and I have pretty much everything done, my problem is getting the window title, I don't want to write the window title every time they press a key, I can get the window title, like I know how to, but how would I only write it to the log when its a new window?
You could maintain an internal list of all windows (with window handles as identifiers to keep memory usage low), and when a new one appears, then you can extract it.
The Win32 API (which I assume you're using) has the function:
EnumChildWindows
which can be used for this task. Call
GetDesktopWindow
to supply as the input window handle, and you'll get every window created under this desktop session.
I'm not sure if this would still work via RDP (and Windows Vista+ have the secure desktop as well as the normal clients), but it depends how vital this functionality is for you.
Store the previous window title and if the current window title is different than the previous window title, print the new window title and set the previous window title to the current window title.
This fails if there's multiple windows with the same name, but it may work for your needs.
Anytime a keypress is detected, call GetForegroundWindow to get the handle to the currently focused window. Store this value as a variable in your program and when it changes, call GetWindowText to get the title of the window and log this title.
Is there way to get the HWND handler of my window?
I'm using win32.
You could call GetActiveWindow to get the active control in your application, then repeatedly call GetParent on the returned handle until it returns NULL. The last valid handle you get should be the handle of your main window.
The easier way as someone else said is to store the returned value from CreateWindow somewhere.
It's probably good to understand why there is no simple way. It all boils down to "which window?". You'll likely have multiple windows visible on your screen, right now. For instance, the taskbar at the bottom of your screen is a window. even your own app typically has more than one. For instance, the "File Save" dialog is a window. Even the simple MessageBox is a window.
So, how do you identify which window you're talking about? The common answer is that you identify them by their HWND. So, to get the position of the "File Save" dialog window, you ask for the position associated with that HWND. Obviously, you can get any property that way, except the HWND itself ! It makes sense to ask the X/Y position of HWND(0x5e21), but it's stupid to ask which HWND belongs to HWND(0x5e21).
Now, it may happen that you have another more-or-less unique property and you want to get the HWND from that. For instance, you may have an X/Y position. In that case, WindowFromPoint(xy) will return the HWND at that position.
But the most common case is that you need to react to a Windows message for your window. In that case, you get the HWND of your window as the first argument of your WindowProc().
So, unless you tell us what unique information you do have, we can't tell you how to find the matching HWND.
Didn't you create your window via CreateWindow() or CreateWindowEx()? The CreateWindowEx() function and the CreateWindow() function both return the HWND of the newly created window.
Also, the operating system passes you the HWND of your window(s) via your window procedure. It's not a function that you call; it's a function that the operating system calls to let your application do any processing that's needed.
In my (PowerBuilder) application, I'd like to be able to determine the graphicobject object which corresponds to a given window handle.
Simply iterating over the Control[] array and comparing the value returned by the Handle() function for each of the child controls doesn't work, since not all objects in my application are children of the main window (consider of login dialogs).
Any PowerScript or C/C++ solution would be acceptable.
Is there maybe some window message I could send to window handles, and this message is only understood by PowerBuilder windows, which would the respond with their internal object name, or the like?
Is it a requirement to determine the object from the handle, or do you just want to identify an object, for example to know where the code you need to modify is? I made a tool that does the latter, but it uses object focus, rather than window handles.
(added 2010-06-21) For windows that aren't children of the main window you could explicitly check each of these window class names with isValid(). Then for each valid window, dig through looking for the handle. This should work as long as you only open one instance of the window class at a time. If you open multiple instances, I think you'll need to add a registration mechanism to the open of those windows so the application has a way to access them.