I'm new to c++ and FindWindowA is working for some processes and not others, for example:
FindWindowA(NULL, "Discord"); will work
but FindWindowA(NULL, "Fortnite"); won't.
anyone know why?
Thanks.
FindWindow only finds top level windows. If you are searching for an exact match with the title of the window, then you must take into account hidden characters (space, tab, etc.).
Even if you find the window title, it will only work if that window isn't localized—i.e., if the program that creates that window is localized for a different language, then you must also localize your search string.
A more reliable approach is to search for the class name, since this will typically not be localized: FindWindow("myclass", NULL);
Of course this will still fail if there is a hidden top level window that creates a child window containing the window you are looking for. To get that window, you can call EnumWindows to get the handle of each top level window, and for each top level window found, you then call EnumChildWindows.
Fortnite's window has a space or two
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.OutputWindow = FindWindow((L"UnrealWindow"), (L"Fortnite "));
sd.SampleDesc.Count = 1;
sd.Windowed = TRUE;
Related
I'm trying to place a window either above or below the icons on the desktop. I mostly just want it to stay attached to the desktop at all times. Similar to Rainmeter or Wallpaper engine. So far, everything I tried either disables interaction, or gets minimized when you use the "Show Desktop" button. Any ideas on how to achieve this? I'm using electron and a native module in node to do this.
It's an old subject, but I'll find out how to do it recently and answer it.
The method is to find the handle of SHELLDLL_DefView, the parent of the desktop window, and then make the SHELLDLL_DefView handle the parent of my window to fix it to the desktop.
The method is to find the handle of SHELLDLL_DefView, the owner of the desktop window, and then make the SHELLDLL_DefView handle the owner of my window to fix it to the desktop.
SHELLDLL_DefView is located under the Progma or WorkerW handle. This is a code to prevent ShowDesktop from being used in the Electget package created by ffi-napi to attach the Electron browserWindow to the desktop.
const GWLP_HWNDPARENT = -8;
// find SHELLDLL_DefView in Progma
const progman = user32.FindWindowExA(ref.NULL, ref.NULL, 'Progman', ref.NULL);
let defView = user32.FindWindowExA(progman, ref.NULL, 'SHELLDLL_DefView', ref.NULL );
// find SHELLDLL_DefView in WorkerW
if (!defView) {
const desktopHWnd = user32.GetDesktopWindow();
let workerW = 0;
do {
workerW = user32.FindWindowExA(desktopHWnd, workerW, 'WorkerW', ref.NULL);
defView = user32.FindWindowExA(workerW, ref.NULL, 'SHELLDLL_DefView', ref.NULL );
} while (!defView && workerW);
}
if (!defView) return false;
// make the SHELLDLL_DefView handle the parent of my window
user32.SetWindowLongPtrA(hWnd, GWLP_HWNDPARENT, defView);
This allows you to create a window where you can click and interact without being hidden by ShowDesktop.
2022-03-29
There was a wrong word, so I corrected it. According to doc, it is not a parent window, but an owner window. In the doc, it is strange that the GWLP_HWNDPARENT constant is related to the parent window. However, when tested with Spy++, the corresponding constant changes the owner window.
To preface we have a strange requirement that all dialogs must be modeless for an MFC application. There is a particular dialog using region drawing and some custom controls to select dates and times for viewing past and future data per view. I need to be able to close this window when it loses focus, the main app gets a system command, etc.
I figured the easiest way to do this would be to register the class like so:
// for CWnd::FindWindow
WNDCLASS wndcls;
SecureZeroMemory(&wndcls, sizeof(WNDCLASS));
wndcls.lpszClassName = L"CTransactionDialog";
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = AfxWndProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hIcon = NULL;
#ifndef _WIN32_WCE_NO_CURSOR
wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
#else
wndcls.hCursor = 0;
#endif
wndcls.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);
wndcls.lpszMenuName = NULL;
BOOL retVal = AfxRegisterClass(&wndcls);
if (!retVal)
AfxMessageBox(L"AfxRegisterClass(CTransactionDialog) Failed");
Then later in response to various event handlers and messages where I would want these modeless window or windows to be closed to do something simple like this:
CWnd* pFound = NULL;
while ((pFound = CWnd::FindWindow(L"CTransactionDialog", NULL)) != NULL)
pFound->DestroyWindow();
However despite the registration of the class succeeding and looking at GetRuntimeClass of the dialog in question in debug and seeing that is matches up as expected the FindWindow never seems to find or close these modeless dialogs as expected.
What am I doing wrong or is there a better way to go about this?
Update: This is how the dialog is created via a static method on the dialog class. The dialog resource for the id specified in create has the Popup property set which should resolve to WS_POPUP style under the MFC covers. The dialog shouldn't and doesn't have a parent as far as I knew.
CTransactionDialog* CTransactionDialog::ShowTransactionDialog(const CRect& crCtrlToFloatAbove, UINT dialogID, Itime defaultTime, Itime initialTime)
{
CTransactionDialog* pCTDialog = new CTransactionDialog(crCtrlToFloatAbove, dialogID, defaultTime, initialTime);
pCTDialog->Create(CTransactionDialog::IDD);
pCTDialog->ShowWindow(SW_SHOW);
return pCTDialog;
}
Update: Doh! FindWindowEx isn't finding anything either.
CWnd::FindWindowEx(AfxGetMainWnd()->GetSafeHwnd(), NULL, L"CTransactionDialog", NULL);
However I have a new plan. I'm just going to make my own window message and handle it on the main frame. I think I can get away with passing a pointer to the dialog as the lParam of the message and then casting it to a CWnd* then calling DestroyWindow. It will work for most cases in a very round about way. I may run into trouble with minimizing and maximizing of the main frame window for dialogs that nothing is holding a pointer too but we'll see.
FindWindow doesn't work with child windows. To find a child window, you can use FindWindowEx, passing the HWND of the parent window as the first parameter.
Class name denotes NOT the c++ class name - it denotes the window class name. This name was used to register the window by the OS and has nothing to do with the c++ class.
May MSDN enlight you...
CWnd::FindWindow does not search child windows.
Is it possible that the mode less window that you are creating has a parent set and that is the reason why FindWindow doesn't find it ?
Below is the simplest and cleanest solution I could come up with:
BOOL CTransactionDialog::OnNcActivate(BOOL bActive)
{
if (!bActive)
PostMessage(WM_CLOSE);
return CDialog::OnNcActivate(bActive);
}
Not 100% sure about this but I think you need to set your class name in the resource file. You are defining a windows class and creating a dialog class but you aren't linking them. Setting a class name in the WNDCLASS struct won't help unless you actually have a way of linking it to the dialog. If you use the resource file and define the dialog, and class name in there then it should work.
I would like to render video in ActiveX control (not in pop-up DirectShow window). I have:
IID_IVMRWindowlessControl
IID_IVMRFilterConfig9
CLSID_VideoMixingRenderer9
I would like to set WindowLess mode, but I don't know how to get HWND of..., exactly, of what? IEFrame, HTML element?
hr = pWc->SetVideoClippingWindow(???);
Anyone with some hint?
Regards.
First of all, add this to the constructor of your ActiveX control:
// this seemingly innocent line is _extremely_ important.
// This causes the window for the control to be created
// otherwise, you won't get an hWnd to render to!
m_bWindowOnly = true;
Your ActiveX control will have a member variable called m_hWnd that you'll be able to use as a render target. without the m_bWindowOnly variable set true, the ActiveX control won't create its own window.
Finally, pick your renderer (VMR9 for example)
CRect rcClient;
CComPtr<IBaseFilter> spRenderer;
CComPtr<IVMRWindowlessControl9> spWindowless;
// Get the client window size
::GetClientRect(m_hWnd, rcClient);
// Get the renderer filter
spRenderer.Attach( m_pGraph->GetVideoRenderer() );
if( ! spRenderer )
return E_POINTER;
spWindowless = spRenderer;
if( spWindowless )
{
spWindowless->SetVideoClippingWindow( m_hWnd );
spWindowless->SetVideoPosition(NULL, rcClient);
spWindowless.Release();
}
spRenderer.Detach();
Please note that my graph object is a custom object and that GetVideoRenderer() is one of my own functions - it returns an IBaseFilter*.
It took me ages to find this one out. ATL is poorly documented, which is a shame, because it's an excellent technology. Anyways, hope this helps!
freefallr's info is extremely helpful, but I don't think it answers your question completely. The trick with windowless activex controls is that you don't get a window. When you draw you'll just basically get a device context and you have to respond to call from the browser and only draw when it tells you to.
The interfaces required are here: http://msdn.microsoft.com/en-us/library/ms682300%28v=VS.85%29.aspx
more info here: http://msdn.microsoft.com/en-us/library/aa751970%28VS.85%29.aspx#OC96_and_Windowless_
We've been meaning to add support for this in FireBreath (http://firebreath.org) for awhile; we have support for it in all npapi browsers, but looks like we don't (yet) support IE. If you find more details, post a summary here =]
Using CWnd::ShowWindow(SW_SHOWMAXIMIZED) maximizes my app window as expected.
However, when clicking the restore button on the app (or double clicking the title-bar), the restored size is the same size as the maximized window, which is confusing for the user.
Using this alternative code has the same problem:
WINDOWPLACEMENT wndpl;
GetWindowPlacement(&wndpl);
wndpl.showCmd = SW_SHOWMAXIMIZED;
SetWindowPlacement(&wndpl);
How can I keep the default un-maximized size when restoring.
I've solved my problem, and the solution might solve yours too. My problem was that even though I called SetWindowPlacement(&wndpl) within CMainFrame::OnCreate the window was not properly restored if it was maximized. I added two lines of code before SetWindowPlacement, and now it works as expected.
CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...
// Obtain wndpl, maybe from registry
AfxGetApp()->m_nCmdShow = wndpl.showCmd;
wndpl.showCmd = SW_SHOW;
SetWindowPlacement(&wndpl);
}
These two lines helps underlying code not to mess things up when calling ActivateFrame, which calls ShowWindow with parameter obtained from CWinApp::m_nCmdShow.
All information are in the file with extension .RC. I never used a Maximize/Restore procedures though you should look for a 'DIALOGEX' for the same window. You can change it using any editor (notepad, ultraedit etc.)
Is there a way for a Windows application to access another applications data, more specifically a text input field in the GUI, and grab the text there for processing in our own application?
If it is possible, is there a way to "shield" your application to prevent it?
EDIT: The three first answers seem to be about getting the another applications window title, not a specific text input field in that window.
I'm no Windows API expert, so could you be more exact how do I find a certain text field in that window, what are the prerequisites for it (seems like knowing a window handle something is required, does it require knowing the text field handle as well? How do I get that? etc...)
Code snippets in C++ really would be really appreciated. MSDN help is hard to browse since Win32-API has such horrible naming conventions.
Completed! See my answer below for a how-to in C++.
For reading text content from another application's text box you will need to get that text box control's window handle somehow. Depending on how your application UI is designed (if it has a UI that is) there are a couple of different ways that you can use to get this handle. You might use "FindWindow"/"FindWindowEx" to locate your control or use "WindowFromPoint" if that makes sense. Either way, once you have the handle to the text control you can send a "WM_GETTEXT" message to it to retrieve its contents (assuming it is a standard text box control). Here's a concocted sample (sans error checks):
HWND hwnd = (HWND)0x00310E3A;
char szBuf[2048];
LONG lResult;
lResult = SendMessage( hwnd, WM_GETTEXT, sizeof( szBuf ) / sizeof( szBuf[0] ), (LPARAM)szBuf );
printf( "Copied %d characters. Contents: %s\n", lResult, szBuf );
I used "Spy++" to get the handle to a text box window that happened to be lying around.
As for protecting your own text boxes from being inspected like this, you could always sub-class your text box (see "SetWindowLong" with "GWL_WNDPROC" for the "nIndex" parameter) and do some special processing of the "WM_GETTEXT" message to ensure that only requests from the same process are serviced.
OK, I have somewhat figured this out.
The starting point is now knowing the window handle exactly, we only know partial window title, so first thing to do is find that main window:
...
EnumWindows((WNDENUMPROC)on_enumwindow_cb, 0);
...
which enumerates through all the windows on desktop. It makes a callback with each of these window handles:
BOOL CALLBACK on_enumwindow_cb(HWND hwndWindow, LPARAM lParam) {
TCHAR wsTitle[2048];
LRESULT result;
result = SendMessage(hwndWindow, WM_GETTEXT, (WPARAM) 2048, (LPARAM) wsTitle);
...
and by using the wsTitle and little regex magic, we can find the window we want.
By using the before mentioned Spy++ I could figure out the text edit field class name and use it to find wanted field in the hwndWindow:
hwndEdit = FindWindowEx(hwndWindow, NULL, L"RichEdit20W", NULL);
and then we can read the text from that field:
result = SendMessage(hwndEdit, WM_GETTEXT, (WPARAM) 4096, (LPARAM) wsText);
I hope this helps anyone fighting with the same problem!
Look at AutoHotkey. If you need an API for your application, look at their sources.
To prevent it, use a custom widget instead of WinForms, MFC or Win32 API. That is not foolproof, but helps.
Yes it is possible in many ways (one way is to use WINAPI GetWindow and GetWindowText).
First, get a handle to the textbox you want to retrieve text from (using FindWindow, EnumChildWindows and other APIs), then:
Old VB6-codeexample, declaration of API:
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Code to extract text:
Dim MyStr As String
MyStr = String(GetWindowTextLength(TextBoxHandle) + 1, Chr$(0))
GetWindowText TextBoxHandle, MyStr, Len(MyStr)
MsgBox MyStr
About how to shield the application to prevent it, you could do many things.
One way would be to have a own control to handle text input that build up the text from lets say a couple of labels placed where the text would be, or that draws the text graphically.
You can also get text from a richedit control with EM_GETTEXTRANGE message, but it works only in the same process in which the control was created.