Find button's HWND in another application - c++

I need to get HWND of button from Anchor Wallet application.
So far, I’ve written this code:
HWND window = FindWindow(0, L"Anchor Wallet (1.3.1)");
HWND class_ = FindWindowEx(window, 0, L"Chrome_RenderWidgetHostHWND", 0);
HWND btn = FindWindowEx(class_, 0, 0, L"Home");
std::cout << btn;
The application window itself and the class of elements in this window I can find, but the button always has the address 00000000.
I tested UI with Inspect.exe. Here’s a screenshot:
Can you please tell me what I’m doing wrong?

Related

Why did I fail to find window use parent specified in Spy++?

Imagine there is a web page with a <input type="file" />. I open this page in Firefox, and click on the file button. Then a dialog will popup.
I want to set the file name edit of the popup dialog programmatically in C++:
First I use Spy++ to check window class, the Firefox window and popup dialog properties in Spy++ look like:
Firefox window:
Handle: 001E013E
Caption: Table with objects - Mozilla Firefox
Class: MozillaWindowClass
Popup dialog:
Handle: 004508BE
Caption: File Upload
Class: #32770 (Dialog)
Spy++ also shows browser window is the parent of popup dialog.
My code looks like:
#include <Windows.h>
#include <stdio.h>
int main()
{
HWND hBrowser = FindWindow(L"MozillaWindowClass", NULL);
printf("Browser hwnd=%X\n", hBrowser);
HWND hDialog = FindWindowEx(hBrowser, NULL, L"#32770 (Dialog)", NULL);
printf("Dialog hwnd=%X\n", hDialog);
system("pause");
}
But the value of hBrowser does not equal the value in Spy++ dialog, and value of hDialog is NULL. I have only one Firefox window opened, with only one tab.
Then I tried to change my code to:
// 0x001E013E is the handle in Spy++
HWND hDialog = FindWindowEx((HWND)0x001E013E, NULL, L"#32770 (Dialog)", NULL);
hDialog still outputs as NULL.
Questions:
Why the handle in Spy++ and the one I get in program is not the same?
Does the "parent window" in Spy++ have the same meaning with the parent parameter in FindWindowEx?
Note: I can't use window title to do the find, due to localization issue (Firefox may be installed in languages other than English).
MozillaWindowClass is the owner of the open dialog, it is not a parent you can use with FindWindowEx. There can also be more than one MozillaWindowClass window so it is better to look for the dialog first:
BOOL CALLBACK FindMozillaOpenFilenameDialogEnumProc(HWND hWnd, LPARAM param)
{
HWND*pData = (HWND*) param;
if (GetClassLongPtr(hWnd, GCW_ATOM) == 32770) // Found a dialog?
{
HWND hOwner = GetWindow(hWnd, GW_OWNER);
if (hOwner)
{
WCHAR buf[100];
GetClassName(hOwner, buf, 100);
if (0 == lstrcmp(buf, TEXT("MozillaWindowClass"))) // The dialog is owned by a Mozilla window?
{
HWND hCombo = GetDlgItem(hWnd, 0x047c); // cmb13
GetClassName(hCombo, buf, 100);
buf[8] = '\0'; // Some Windows versions use ComboBox and some use ComboBoxEx32, we only care if it is some type of combobox
if (0 == lstrcmp(buf, TEXT("ComboBox"))) // The dialog contains a ComboBox with the expected ID?
{
*pData = hWnd;
return false;
}
}
}
}
return true;
}
int main()
{
HWND hDialog = NULL;
EnumWindows(FindMozillaOpenFilenameDialogEnumProc, (LPARAM) &hDialog);
printf("Dialog hwnd=%X\n", hDialog);
if (hDialog)
{
HWND hCombo = GetDlgItem(hDialog, 0x047c);
SendMessage(hCombo, WM_SETTEXT, 0, (LPARAM) TEXT("c:\\foo\\bar.exe")); // Could also use CDM_SETCONTROLTEXT?
}
return 0;
}
This code relies on undocumented and internal names and window relationships, it could break at any time.
Keep in mind that "MozillaWindowClass" is a internal Mozilla name and could change at any time. The documented cmb13 id of the filename control is only documented for GetOpenFileName and GetSaveFileName but not for IFileDialog based dialogs. You really should use UI Automation when you interact with the open dialog in another application!

create a CAxWindow inside a BHO (C++)

I'm having trouble opening a new CAxWindow inside my BHO, I can see the request to "microsoft.com" being fired but no window is shown.
I tried many different ways, this is my last, anyone has a clue what's wrong?
thanks.
CAxWindow m_axWindow;
CRect rc;
HWND wndIE = NULL;
m_pWebBrowser->get_HWND((SHANDLE_PTR*)&wndIE);
GetWindowRect(wndIE, &rc);
CSize sz = CSize(100, 200);
CRect rcPage = new CRect(10, 10, 10, 10);
m_axWindow.Create(wndIE, rcPage, _TEXT("http://www.microsoft.com"), WS_POPUP | WS_TABSTOP, 0, 0U, 0);
HRESULT hRet = m_axWindow.QueryControl(IID_IWebBrowser2, (void**)&m_pWebBrowser);
I think m_axWindow.Create creates a child window. Check its style for WS_CHILD after that call. You probably need to create a plain popup top-level window first, then create a CAxWindow using that popup window as parent, not the wndIE. Make sure to do ShowWindow on the pop-up, too.

how to change the position of the child window inside the parent window and show the toolbar?

I have the following code which passes a window handler form OpenCV window to win32 handler, therefore I can show the grabbed images from camera to the screen and the images will show as a child window of my main API.
but the problem is that when I want to add a tooldbar to my program, the image window handler comes at the top of the toolbar. how can I sort this out?
//create a window and set the handler from openCV to win32
cv::namedWindow("test",cv::WINDOW_AUTOSIZE);
hWnd2 = (HWND) cvGetWindowHandle("test");
hParent = ::GetParent(hWnd2);
::SetParent(hWnd2, hWnd);
::ShowWindow(hParent, SW_HIDE);
_liveCapturing=true;
lastPicNr = 0;
SetWindowTextW(hStatus, L"Live Capturing ... ");
if(FullScreen()){
::ShowWindow(hWnd, SW_MAXIMIZE);
}
code for the toolbar :
HWND CreateToolbar(HWND hwnd){
HWND hTbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_TOP , 0, 0, 0, 0, hwnd, (HMENU)12, GetModuleHandle(NULL), NULL);
SendMessage(hTbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
TBBUTTON tbb[3];
TBADDBITMAP tbab;
tbab.hInst = HINST_COMMCTRL;
tbab.nID = IDB_STD_SMALL_COLOR;
SendMessage(hTbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
return hTbar;
}
Probably you have found the solution a long time ago, but i want to post my anwers in case other users need it.
You can simply add the OpenCV window with the same code you have to a child window in your window (which you set it position in advance). For example you can add it to a static text window (label) ...
If you want to move the OpenCV window, call SetWindowPos() with the desired coordinates.
SetWindowPos(hWnd2, 0, 0, 30, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

Couldn't find child window using FindWindowExA()

Trying to get button's handle on window calculator's form.
Spy++ shows the following tree:
("Calculator"; CalcFrame) ->
(""; CalcFrame) ->
(""; #32770 Dialog), ...anather child windows ->
(""; Button) ,... another child windows
// ("window caption"; window class)
// -> next child level
I catch main window and go deeper using FindWindowExA();
#define wndName "Calculator"
...
HWND calcHwnd = ::FindWindowA(0, wndName);
HWND frameHwnd = ::FindWindowExA(calcHwnd, 0, 0, 0);
HWND contentHwnd = ::FindWindowExA(calcHwnd, 0, "#32770 (Dialog)", 0);
DWORD er = GetLastError();
I could use ::FindWindowExA(calcHwnd, 0, 0, 0) several times to get the HWND I need(at that level there are several child windows). but i want to get HWND using condition that the window i need has class "#32770 (Dialog)".
But ::FindWindowExA(calcHwnd, 0, "#32770 (Dialog)", 0) - returns NULL. GetLastError returns 0. What is wrong?
#32770 is actually a class atom. Try:
HWND contentHwnd = ::FindWindowExA(calcHwnd, NULL, MAKEINTRESOURCE(32770), NULL);

CDialog doesnt show in task bar

Im trying to get a CDialog that has no border or frame to show in the task bar.
It is created in the InitInstance of CWinApp (used to update the app) and i have tried setting the WS_EX_APPWINDOW flag but it still doesnt show in the task bar.
Any ideas?
Edit:
As defined in the resource:
IDD_UPDATEFORM_DIALOG DIALOGEX 0, 0, 246, 124
STYLE WS_POPUP
EXSTYLE WS_EX_APPWINDOW
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
END
As used:
UpdateForm *dlg = new UpdateForm(UPDATE_FILES, CWnd::GetDesktopWindow());
INT_PTR nResponse = dlg->DoModal();
UpdateForm::UpdateForm(int updateType, CWnd* pParent) : CDialog(IDD_UPDATEFORM_DIALOG, pParent)
{
m_bInit = false;
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON);
m_Progress = new DesuraProgress();
m_updateType = updateType;
}
Still Shows up like so:
http://update.goldeneyesource.net/lodle/noicon.jpg http://update.goldeneyesource.net/lodle/noicon.jpg
Edit #2:
To set the icon for this window (essentially a splash screen), you can send the window a WM_SETICON message along with a desired icon.
For a dialog, you can do this in OnInitDialog(). Here's a snippet that uses the default windows information icon as noted here: LoadIcon # MSDN.
// CHelperDlg message handlers
BOOL CHelperDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 32516 is also known as IDI_INFORMATION
HICON hIcon = LoadIcon(0, MAKEINTRESOURCE(32516));
// 0 in WPARAM is 'small version'
::SendMessage(GetSafeHwnd(), WM_SETICON, 0, (LPARAM)hIcon);
// 1 in WPARAM is 'large version'
::SendMessage(GetSafeHwnd(), WM_SETICON, 1, (LPARAM)hIcon);
// No cleanup as HICONs are free from disposal rules.
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
--
Edit:
I created a second project to mimic your update, but I don't see any differences except the inclusion of DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS) in my .rc file. These dialog style definitions don't affect the display of the dialog.
I've uploaded key parts for my minimal example to http://gist.github.com/461057 for your reference, in case you'd like to try adding this dialog ahead of yours for testing.
Also, I'm using VS2010. I have VS2008 available if you'd like me to repeat this test in that version as well.
--
Original:
Try specifying the desktop window (via CWnd::GetDesktopWindow()) as the parent window when you create the dialog.
// Member Variable
CHelperDlg *dlg;
// Meanwhile, elsewhere...
dlg = new CHelperDlg();
dlg->Create(IDD_HELPERDLG, CWnd::GetDesktopWindow());
dlg->ShowWindow(SW_SHOW);
// or...
// dlg->DoModal();
Also, don't forget to destroy the dialog when you're done with it, either in the destructor of the class owner, or other convenient location.
I figured out a hack to get this to work. Instead of disabling the toolbar/caption bar styles to get no border, i used SetWindowRgn to clip the frame and title bar. Same affect, less issues.
RECT rect;
GetWindowRect(&rect);
int w = rect.right - rect.left;
int h = rect.bottom - rect.top;
HRGN region = CreateRoundRectRgn(5, 30, w-5, h-5-30, 5, 5);
SetWindowRgn(region, true);