How to set keyboard focus to NULL window in wxWidgets? - c++

In WinAPI you can call global function SetFocus(HWND) to set focus to NULL window (keystrokes are ignored):
::SetFocus(NULL);
wxWidgets have wxWindow::SetFocus(void) virtual member function so you cannot pass NULL. How to do portable equivalent of ::SetFocus(NULL) in wxWidgets?

There is no way to do it in wxWidgets API (but then it's not clear why would anybody want to do it).
You can ignore all keys by checking for the corresponding events in wxApp::FilterEvent() if you need to do it globally.

Related

Getting handle of current window to GetWindowText?

I want to display the Title of the Dialog box:
HWND hWnd = ::GetActiveWindow();
char cc[101];
::GetWindowText(hWnd,cc,100);
MessageBox(cc);
but the result yields a blank "".
not sure what is wrong??
According to MSDN:
Retrieves the window handle to the active window attached to the calling thread's message queue.
This means that if the thread which you are calling the function from doesn't own any window, the function will fail.
You probably want GetForegroundWindow instead.
This may coming a bit late but anyway. If you want to get the current (active) window on the system at any time, the best approach is by using a procedure implemented in a DLL, then installing a global hook that call this procedure.
The following resources are quite helpful:
Creating and using your DLL
An overview on Hooks

API method for getting window's controls

I've searched quite a while in MSDN, couldn't find it.
In fact, I don't even know how controls are called in API. they are not declared as a "Window", right? (No hwnd for them, I wasn't sure because I saw a method which seemed like it could return a control but it returns an hwnd.)
So lets say I have a window's handle. I want to recieve it's controls (a textbox, button, checkbox....)
What are the methods to do this? And again, how are the controls called in API?
Thanks for helpers.
They're called Windows and HWNDs are handles to these windows, just like a fopen() returns a handle to a file.
These are all the functions you'll need. Try EnumChildWindows

DeferWindowPos weird behaviour

This happens with all ActiveX controls. If I reposition an ActiveX control with DeferWindowPos
HDWP hdwp = BeginDeferWindowPos(1);
DeferWindowPos(hdwp, m_pActiveX->GetSafeHwnd(), NULL, left, top, width, height, SWP_NOZORDER);
EndDeferWindowPos(hdwp);
it goes there but then moves/resizes to its old rectangle once you click anywhere inside the control. If I use MoveWindow instead
m_pActiveX->MoveWindow(left, top, width, height);
this doesn't happen.
It doesn't happen with any other type of control, only with ActiveX controls, but it happens with all of them. I made a test to confirm this, creating a new ActiveX control project and didn't make any changes, and the problem was still there.
You never got an appropriate answer. I'll try to help out a bit here.
The issue is that MFC hides a lot of the trickiness with hosting an ActiveX control within it's framework. Specifically, if you step into the MoveWindow call, it is not simply a wrapper around the Win32 MoveWindow function. It calls into the OLE Control Container support classes. This basically says, if we have a control site interface, then call COleControlSite::MoveWindow, otherwise call the standard Win32 MoveWindow. The same occurs with several other window functions handled by CWnd etc. For example COleControlSite::SetWindowPos handles hiding/showing the control, then calls COleControlSite::MoveWindow to move it, and then finally calls ::SetWindowPos (with the move/show flags masked out) to handle the rest.
Once within COleControlSite::MoveWindow, you will notice it does several things: it calls SetExtent, updates it's internal m_rect member, and then calls SetObjectRects.
Bypassing these for ActiveX controls using the Win32 API directly (eg via DeferWindowPos) causes some of these crucial steps to be missed. Depending on how your code is layed out, usually you can handle this yourself.
What is this ActiveX control?
Apart from that consider that DeferWindowPos is meant for positioning multiple windows at the same time. The concept being you enter the begin statement, change a bunch of window positions for a new layout, then end to actually move and apply the new positions and sizes.
If you aren't updating multiple windows consider using SetWindowPos instead.
Consider also that you may be getting a message to move, resize, or change the windows position while you are deferring. To prevent this if that is what is happening pass the SWP_NOSENDCHANGING flag in each call to DeferWindowPos so that it is not sent or handle the message and clear all the bits in the WINDOWPOS struct received to prevent unwanted changes.
It is also possible for this call to fail ... are you checking the return value?

how to find a window's SW_SHOW/SW_HIDE status

I am trying to determine a window control's visibility that has been hidden or enabled with CWnd::ShowWindow(). (or ::ShowWindow(hWnd,nCmdShow))
I cannot simply use ::IsWindowVisible(hWnd) as the control is on a tab sheet, which may itself be switched out, causing IsWindowVisible to return FALSE.
Is there a way to get the SW_SHOW/HIDE (or others) window status or do I need to use the retun value of ShowWindow() and reset accordingly?
edit:
as the control is enabled (or disabled) to show, but may not be currently visible, as the tab is switched ot, I would think that it's SW_SHOW status would remain the same, even if the window itself is not actually switched in. If I'm unrealistic in my expectations that that's fine.
So really I'm looking for 'can this window/control be shown'
Call GetWindowLong( handle, GWL_STYLE), check the returned value for WS_VISIBLE style presence.
Use GetWindowPlacement. It fills WINDOWPLACEMENT structure, which has field showCmd.
showCmd
Specifies the current show state of the window. This member can be one of the following values.
I would use GetWindowPlacement, however I am not sure if I understood what you want.
It fills in a WINDOWPLACEMENT structure and then use the showCmd member.
GetWindowPlacement() function will work only if the window is maximized or minimized. Otherwise, showCmd member will return SW_SHOWNORMAL also when window is hidden, as pointed out in this StackOverflow answer: WINDOWPLACEMENT's showCmd... always 1?
You can use the more straightforward boolean function IsWindowVisible() to get if the specified Window is in a visible state or not.
If it is a multi-tab dialog and not a control, then override as
void MyClass::OnShowWindow(BOOL bShow, UINT nStatus)
{
m_nCmdShow = bShow;
CDialog::OnShowWindow(bShow, nStatus);
}
In BEGIN_MESSAGE_MAP, add ON_WM_SHOWWINDOW().
m_nCmdShow now has the status if the window is SW_SHOW or SW_HIDE.
I don't know if there is a proper method for this task but I would try WindowFromPoint Function.
Remarks
The WindowFromPoint function does not retrieve a handle to a hidden or
disabled window, even if the point is
within the window. An application
should use the ChildWindowFromPoint
function for a nonrestrictive search.
For example I would convert control's corner coords into screen coords and then try to get it's handle from those points.

How to add custom item to system menu in C++?

I need to enumerate all running applications. In particular, all top windows. And for every window I need to add my custom item to the system menu of that window.
How can I accomplish that in C++?
Update.
I would be more than happy to have a solution for Windows, MacOS, and Ubuntu (though, I'm not sure if MacOS and Ubuntu have such thing as 'system menu').
For Windows, another way to get the top-level windows (besides EnumWindows, which uses a callback) is to get the first child of the desktop and then retrieve all its siblings:
HWND wnd = GetWindow(GetDesktopWindow(), GW_CHILD);
while (wnd) {
// handle 'wnd' here
// ...
wnd = GetNextWindow(wnd, GW_HWNDNEXT);
}
As for getting the system menu, use the GetSystemMenu function, with FALSE as the second argument. The GetMenu mentioned in the other answers returns the normal window menu.
Note, however, that while adding a custom menu item to a foreign process's window is easy, responding to the selection of that item is a bit tricky. You'll either have to inject some code to the process in order to be able to subclass the window, or install a global hook (probably a WH_GETMESSAGE or WH_CBT type) to monitor WM_SYSCOMMAND messages.
Once you have another window's top level handle, you may be able to call GetMenu() to retrieve the Window's system menu and then modify it, eg:
HMENU hMenu = GetMenu(hwndNext);
You can use EnumWindows() to enumerate top level Windows.
I don't have a specific answer for the second part of your question, but if you subclass the window, I imagine you can modify the system menu.
EDIT: or do what Chris said: call GetMenu()
Re: the update - please note that not even Microsoft Windows requires windows to have a sytem menu. GetMenu( ) may return 0. You'll need to intercept window creation as well, because each new top window presumably needs it too.
Also, what you propose is rather intrusive to other applications. How are you going to ensure they don't break when you modify their menus? And how are you going to ensure you suppress the messages? In particular, how will you ensure you intercept them before anyone else sees them? To quote Raymond Chen, imagine what happens if two programs would try that.