Windows Dialog Box not getting opened - c++

Im trying to open a Dialog box in Windows machine(using windows credential provider), when the user presses a button. i tried the below code but, dialog box is not getting opened. i have a resource "IDD_DIALOG1" and callback method "ChangePasswordProc".
HWND hwndOwner = nullptr;
::DialogBox(HINST_THISDLL, MAKEINTRESOURCE(IDD_DIALOG1), hwndOwner,ChangePasswordProc);

I didn't write in Windows GUI for a looong time, but perhaps try something like this:
HWND dialog = ::DialogBox(HINST_THISDLL, MAKEINTRESOURCE(IDD_DIALOG1), hwndOwner,ChangePasswordProc);
ShowWindow(dialog, SW_SHOW);
I remember, that creating window does not imply showing it - it must be done explicitly.

To create any window from inside of Credential Provider you must first get parent window handle by calling OnCreatingWindow method of ICredentialProviderCredentialEvents interface.
HRESULT OnCreatingWindow([out] HWND* phwndOwner);
Pointer to this interface is supplying to your provider by calling Advise method of its ICredentialProviderCredential interface :
HRESULT Advise([in] ICredentialProviderCredentialEvents* pcpce);
Have a look at this post.

Related

SetProgressValue() not working within ConEmu

We developed a console application which uses ITaskbarList3::SetProgressValue() method that works fine when that application is invoked within cmd.exe but it doesn't show any progress when invoked within Conemu console. No error messages happens anywhere either. The HWND passed as parameter of ITaskbarList3::SetProgressValue() is get like this:
HWND hwnd = GetConsoleWindow();
I have no code to show because I don't know an alternative method to do this or what might be issue. I thought the returned HWND could be conemu's rather my application's so I called GetWindowText() function to check if the window's text was other than my console application but it was a string in same format as cmd's.
When you run console application in ConEmu the GetConsoleWindow() returns virtual console HWND rather than native conhost HWND. However both sent suitable for SetProgressValue() because virtual console is a child window of ConEmu (which is shown on the TaskBar) and conhost HWND is not even visible.
Just get parent of the GetConsoleWindow() before calling SetProgressValue().

how to make a clickable button in c++ win32

anyone can tell me how to use a bitmap as a button, actually i can create a static control and could set a picture to it but the thing is that i don't know how to use it as a button, i am using c++ win32.
This is how i create the bitmap
Code:
HWND Profile_Stuff(HWND hWnd, HINSTANCE hInst)
{
HWND Profile_Pic;
Profile_Pic = CreateWindow("STATIC", NULL, SS_BITMAP|WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER, 5,5,33,33, hWnd, NULL, hInst, NULL);
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "camera1.jpg", IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
if(hBmp == NULL){
MessageBox(NULL, "Error while loading image", "Error", MB_OK|MB_ICONERROR);
}
SendMessage(Profile_Pic, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
return 0;
}
then i call the function in main window wm_create message handler which creates it successfully, now i don't know to use it as a button, like we have a picture of an advertisement at the bottom of bit torrent application.
i am using visual studio c++ with win32 api.
If you want a button control, you should create a button control. The visual representation can be controlled by the application. To do so, specify the BS_OWNERDRAW Button Style. A button control with this style sends a WM_DRAWITEM message to the control parent whenever a visual aspect has changed. The control parent can then render the control as it sees fit.
An introduction to owner-drawn controls is available at Custom Controls. If you wish to retain some parts of the button control (e.g. its border), see Using Visual Styles with Custom and Owner-Drawn Controls for details (or DrawFrameControl if you aren't using Visual Styles).
Fully working sample code for an owner-drawn button control can be found in this answer.
In Windows, the windows belong to a class, a the class defines the windows procedure for all windows of that class, meaning how they react to events.
If you create a STATIC window, it will not react to any click and will not be useable as a button.
You could create a custom class, register it along with a custom windows procedure able to mimic a BUTTON. But unless you have very special requirements just create an owner drawn button as shown in #IInspectable's answer

::PostMessage doesn't work when I am tabbed in to another program

In our Program we have a Dialog from a separate dll open to display infomation. I need to close this dialog when our system timer causes the system to lock.
I send information to the dll by registering a system message in both my MainFrm and EditDisplayDll
SYSTEMLOCK = RegisterWindowMessage("SystemLock");
When I sent the message via
::PostMessage(GetActiveWindow()->m_hWnd,SYSTEMLOCK,0,0);
The message correctly sends to my EditDisplayDll and closes the dialog when the system locks; however, if I alt tab while waiting for the timeout and use another program(firefox, outlook, etc.) the message never correctly calls to the EditDisplayDll. The MainFrm and other windows inside of the MainFrm correctly lockout and hide themselves in either case.
I have tried also using HWND_BROADCAST with PostMessage and SendNotifyMessage. I have also tried to use FindWindow() and FindWindowEx() to specifically call the EditDisplayDll.
I cannot use something like GetDlgItem() because my MainFrm.cpp doesn't have access to this dll.
My decision to use GetActiveWindow() was because I believe it looks to windows specific to my program no matter what window I am in as seen in the imagery in Foreground Vs Active window
Finally, my question is, is there a way to call all Windows in my program no matter what program I am currently in or is there another way I could get access to the specific IDD of the EditDisplayDll in order to send the SYSTEMLOCK message to it?
CWnd *cWndED = FindWindow(_T("EditDisplay"),_T("EditDisplay")); HWND
hwnd = (HWND)cWndED;
You should use win32 API ::FindWindow with proper class, window name. And do not cast CWnd pointer to HWND. Your code should look like:
HWND hWnd = ::FindWindow(_T("ProperClass"), _T("ProperNmae"));
if (hWnd != NULL)
{
::PostMessage(hWnd, YOUR_MESSAGE, ....);
}
I will suggest you to find your Dll window class and name using Spy++ and then try to find that using above method. Remember it's always better to use native API for this kind of tasks.
FindWindow is a good solution if you know both, name of the window and the element.
If you want to get the HWND of your window - no element inside the window -, you can pass as first parameter NULL.
::FindWindow(NULL, _T("WindowName"));
Back to your code: If you are lucky your PostMessage does nothing, otherwise the active window may catch your message. Who knows how/if it is handled in the active window ? Use the PostMessage if you have a valid IsWindow(HWND) from FindWindow or FindWindowEx.
In case you want a CWnd from your HWND take a look at this. (The call may be slow)
HWND hWnd = ::FindWindow(_T("ClassName"), _T("WindowName"));
if (hWnd && IsWindow(hWnd))
{
::PostMessage(hWnd, MESSAGE_TO_BE_SEND, lParam_or_Flags);
}

Why CreateDialog failed with error code 5 in BHO?

I use CreateDialog to create a modeless dialog in SetSite method after get the IWebBrowser2 interface. The dialog resource is in the BHO dll. When create a new instance (I mean doble click the IE shortcut) of IE the creation is successful but when I create a new tab the creation is failed (but in other computer it is successful). there is also something strange is that sometimes create a new tab will also create a new IE process but sometimes will not.
This is the code for dialog creation:
bool MyDialog::Create(MyContext *ls)
{
extern HINSTANCE hInstance; // handle of BHO dll
m_hDialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MYDLG),ls->GetBrowserMainWnd(), MyDlgProc);
if (m_hDialog) {
SetWindowLong(m_hDialog, GWL_USERDATA, (LONG)ls);
SetTimer(m_hDialog, 1, 1000, NULL);
return true;
}
return false;
}
I think this has something to do with dialog creation in different UI thread but not sure about this. Hope somebody can help me with this problem. Thanks a lot!
Update 2014-03-31:
The GetBrowserMainWnd method call IWebBrowser2->get_HWND to get the main window handle. But for IE7 and later the introduced tabbed window makes things complex as MSDN's description:
"Internet Explorer 7. With the introduction of tabbed browsing, the return value of this method can be ambiguous. To alleviate confusion and maintain the highest level of compatibility with existing applications, this method returns a handle to the top-level window frame, not the currently selected tab."
So, I use the example code (refer to http://msdn.microsoft.com/en-us/library/aa752126(v=vs.85).aspx) solved this problem.
It seems that the root cause is the third parameter hWndParent. When I set it to NULL this problem disappear. I think the new process of an IE tab can't access the IE main window handle so failed with error code 5.

Find a window using c++ and modifying controls

I would like to use c++ without mfc(and not clr) in order to modify textbox's and activate a button on a form outside of my project. I don't know where to start. I've done a lot of searching but can only find information for VB. A starting point would help.
Thanks.
I tried this and it doesn't seem to work.
HWND fWindow = FindWindow(NULL ,(LPCWSTR)"title");
and I also tried this
HWND fWindow = FindWindow(NULL ,LPCWSTR("title"));
I ALSO tried using LPTSTR instead of LPCWSTR, incase it was a unicode deal.
Maybe I don't understand this microsoft LPCWSTR and LPTSTR crap.
I also tried
HWND fWindow = FindWindow(NULL,TEXT("title"));
and that didn't work.
I guess the windows api must just be broken.
I tried the function on other programs...I'm using xp and I tried catching the calculator, and an explorer window, and something else. But I got nothing.
Heres some of the exact code I'm using to try and figure this out.
HWND face = NULL;
face = FindWindow(NULL,TEXT("My Computer"));
LPSTR title = TEXT("");
GetWindowText(face,title,250);
if(face != NULL)
{
MessageBox(NULL,title,TEXT("WOOP"),1);
}
face = nothing.
title = ""
Bear in mind, I'm not actually trying to hook explorer, I just want to figure out how to get it to work.
Use spy++ or winspector to see the actual "text" of the window.
(Strictly speaking, the caption of the window need not match it's window text. Especially true of "fancy" windows which paint their own caption.)
The following works fine for me (using Calc.exe to test).
HWND hwnd = NULL;
hwnd = FindWindow(NULL,_T("Calculator"));
TCHAR title[251];
if(hwnd != NULL)
{
GetWindowText(hwnd,title,250);
MessageBox(NULL,title,_T("WOOP"),MB_OK);
}
else
MessageBox(NULL,_T("No such window."),_T("OOPS"),MB_OK);
Edit: You should have used _TEXT instead of TEXT.
One way to do this is to use FindWindow to get a handle to the form. Then if you know the button and edit window Ids, you can use GetDlgItem to get their window handles. If you dont know the ids, you can use EnumChildWindows to examine all of the controls on the form.
Once you have the window handles for the controls, you can use SetWindowText to set the text on the edit control, and send a WM_COMMAND message to the form window with the button ID as the command value to make the form think that the button has been clicked.
There are a lot of ways to go about this once you have the correct window handles. There are security issues when you use the window handles of another process, but if the process isn't secured, then inter-process use of window handles just works. For a secured process, you won't be able to find out the window handles.
The windows API provides Methods for this. These should be independent of MFC and CLR, as they are plain win32. I had a project once accessing the Form fields of an Applictation from a loaded DLL (don't ask why).
you might want to look here (Codeproject)
or here (msdn)
At first, you need to obtain a handle to the process you want to access.
When have this, you can use GetDlgItem() (search msdn for that) to retrieve a handle to the desired textbox.
With this handle, you should be able to modify the control in question.
If your trying to get big (and do some more UI automation), you sould have a closer look at these:
Microsoft Active Accessibility
IAccessible2
Microsoft UI Automation
Windows Automation API (Win7)