SetProgressValue() not working within ConEmu - c++

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().

Related

Windows Dialog Box not getting opened

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.

::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);
}

How can I register another win32 message handler

I want to change the message handler for an old legacy app we use but don't have the source for any more. In a dll that we do have the source for I'm wanting to intercept the window messages and then pass them onto the app. Is this possible? I tried something along the lines of:
WNDPROC lpfnWndProc = NULL;
void GetHandler()
{
HINSTANCE hInstance = GetModuleHandle(NULL);
HWND hWnd = GetActiveWindow();
WCHAR lpClassName[1024];
GetClassName(hWnd,lpClassName,1024);
WNDCLASSEX wc;
GetClassInfoEx(hInstance, lpClassName, &wc);
lpfnWndProc = wc.lpfnWndProc;
wc.lpfnWndProc = NewMessageProc;
RegisterClassEx(&wc);
}
However GetActiveWindow fails and just returns NULL. Is there a simpler way to do this. Infact I'd be happy if I could just simply add another message handler.
It is not clear whether you want to subclass specific controls, or all windows of a particular window class.
If you want to subclass specific controls, the section Subclassing Controls in the MSDN describes how to do this, both for ComCtl32.dll version 6 and above, and the legacy procedure of directly replacing a control's window procedure.
If you want to subclass all controls of a particular window class you would have to change the entries stored in the registered window class, using SetClassLongPtr. Note that this will only affect windows subsequently created with that window class. This is a bit of a Catch 22, as you need to have a window handle when calling SetClassLongPtr, limiting the applicability of subclassing a window class.
As for the code you posted, there are a number of issues:
Your call to GetModuleHandle retrieves the wrong HINSTANCE, namely that of the calling application. Since you need the module handle of the module that registers the window class you have to pass the name of the .dll that implements the controls.
Calling GetActiveWindow may or may not return a value, depending on whether or not the calling thread actually does have an active window. In your case it apparently doesn't, so you need another means of retrieving a window handle, such as FindWindowEx.
Your final call to RegisterClassEx doesn't do what you think: It will simply fail, since you cannot re-register a window class with the same name of an existing window class. You need to call SetClassLongPtr instead, as illustrated above.
I'd actually use SetWindowSubclass after getting the HWND of the window you want to modify the behaviour of. SetWindowLong was deprecated as a way to change the WndProc of a window back around the time that CommCtrl.dll version 6 came out. MSDN can tell you all about that particular part of history and its motivation - just look up SetWindowSubclass.
As it stands, assuming the calling thread has an active window, your code will simply create a new window-class with the same attributes as your target window, albeit with a different WndProc - it wont set the wndproc of an existing window.. - (hence my mention of SetWindowLong and SetWindowSubclass)
EDIT: Or at leaast, it would of not for the oversight I made on that point. As pointed-out in a comment below, this call to RegisterClass will actually fail - you can't register the same className more than once.
You should also probably look at the FindWindow function - just give it a NULL lpWindowName, and the (known) class-name of the target window. In the event that the desired window is not the one that's returned, you could use EnumWindows. Simply call GetClassName in the callback function you supply to EnumWindows, subclassing any/all windows whose class-name matches the class-name of the target window.
Once this window has been subclassed, you can consume its messages as you wish, passing them onto the original window-proc as needed.

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

How to get HWND in win32?

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.