How can I get a winMain's HWND hwnd's hInstance application handle without using globals? I'm trying to make a dialog box to be sent to the LRESULT CALLBACK to have certain menu items make it show up.
Or is different way to set this up. I've done it with globals already but I can't seem to figure out how to set it up inside the LRESULT CALLBACK
I tried
HINSTANCE hInst = (HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE);
HWND hDlgbox = CreateDialog(hInst, MAKEINTRESOURCE(ID_TOOL_BOX_CREATE) ,hwnd, ToolProc);
in the wndproc but that only makes it show up once then never appears again when I try to open it using a popupmenu item and the buttons and items don't seem to receive messages in the dialog box when made this way in the wndproc.
So what I did was
in win main
HWND hdlg;
set wndextra to size of a hwnd.
then create your dlg box however you do it.
SetWindowLongPtr(hwnd, 0, (LONG_PTR)hdlg);
and in winproc
hwnd somenewDlg
somenewDlg = (HWND)GetWindowLongPtr(hwnd, 0);
Related
I'm working on some CreateWindow things.
My work need I to insert a Button into one of an Application's Window, and when I click the button, my application can do something. That Application isn't my Application, so I think I need to do some "hook thing".
And I tried this:
HWND hwnd = FindWindowEx("className",NULL)
CreateWindowEx(...hwnd...)
Its worked. The Button successfully inserted into target application.
but when I try to handle that window's message
I failed.
This hwnd is belongs to my application hInstance, but my Application has its own message loop by CEF.
I tried SetWindowsHookEx,but its not working.
Whatever I do, it will not handled.
and if i use while(GetMessage (&messages, NULL, 0, 0)),it will block my application's thread
WNDCLASS xxx and RegisterClass(xxx)
or CreateWindow(className)
confused me.
I try to use LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) but the while() will block my application's thread
and in my application's wndProc, there is no WM_COMMAND message in.
HWND hwnd = FindWindowEx(0, 0, L"TCustomBaseForm" , NULL);
HWND hwndButton = CreateWindowEx(0L,_T("Button"), L"Btn", WS_CHILD|WS_VISIBLE| BS_PUSHBUTTON, 435, 45, 35, 45, hwnd, NULL, GetModuleHandle(0), 0);
DWORD dwProcId = 0;
DWORD dwThreadId = 0;
dwThreadId = GetWindowThreadProcessId(hwndButton, &dwProcId);
SetWindowsHookEx(WH_MOUSE, Hookproc, g_hInstance, dwProcId);
Until now, my "inserted button" never work.
So, is there any way to make this "inserted window" or button same as a MFC button that, when I click it, I can handle a message like WM_LBUTTONCLICK in my WndProc?
A button sends a WM_COMMAND message to its parent window when you click it.
There are at least two ways to deal with this without hooking:
Create the button as a child of a STATIC control (or a custom window) that you also create. You need to subclass the STATIC control to receive the message.
Subclass the button and catch the mouse up message and space/enter key-down messages.
Thank you all. I did it.
I create a Window that have a button. And I use SetParent(myWindowHwnd,myTargetWindowHwnd) and handle the button's click event in my window, it works.
No hook, no problems.
Thank you all very much.
And thanks for edit my question, for my poooooooooooor English.
I've learned a lot about Windows Hook.
I have the process name and the handle (HWND) of its window. I want now to get the relative icon (if available). Searching through MSDN, I found ExtractIcon() to get the handle to the icon from a given exe name, and GetIconInfo() to get "information" of the icon from the HICON. I don't know if it's the right way to do this, and how to retrieve correct information to show (in a second moment) the icon without the handle to the icon.I have to send this information to another process (through socket) that has to show the icon.In the ICONINFO structure there are HBITMAP fields that contains the bitmap (black&white and with colour). Is it useful?
you can use the API GetClassLong to retrieve the icon associated with your program then use SendMessage API passing the hwnd of of the window you want to change it's icon.
in this Example I extracted the icon from my application then set it to Calculator. my windows calculator is open before sending to it the icon:
case WM_LBUTTONDOWN: // just for explanation so left clicking in your client area and see the result
{
HICON icon = (HICON)GetClassLong(hWnd, GCL_HICON);
HWND hCons = FindWindow(NULL, "Calculator"); // I already opened windows calculator. you can use any other window but be sure to get its valid Handle
if(!hCons)
MessageBox(0, "\"Calculator\" windows is not found!", 0, MB_OK|MB_ICONHAND);
SendMessage(hCons, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)icon); // setting the icon
}
break;
How to show custom messages using a dialog box in Win32 API rather than show them in a default MessageBox function?
I made a function as follows:
void DialogBox_Custom (HWND hWndParent, LPSTR contentToShow)
{
HWND hDialog = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), hWndParent, DialogProc);
if (!IsWindowVisible(hDialog))
{
ShowWindow(hDialog, SW_SHOW);
}
SetDlgItemText(hDialog, IDC_EDIT1, contentToShow);
}
But when I call this function, the dialog box is appearing like millions of times per second and never ending until I close the program by force.
Please kindly someone help me make a custom dialog box where I can show some content sent from the parent window to an EDIT control window in the dialog box.
Use the DialogBoxParam function to create the modal (suspend execution until the window is closed) dialog box.
DialogBoxParam(instance, MAKEINTRESOURCE(IDD_YOURDIALOG), hWndParent, YourWndProc, (LPARAM)contentToShow);
You then have to create a function YourWndProc to handle the messages to paint and offer a mechanism to close the window, to allow execution to continue after your DialogBox() call.
INT_PTR CALLBACK YourWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
SetDlgItemText(hDlg, IDC_EDIT1, (LPSTR)lParam);
return (INT_PTR)TRUE;
case WM_CLOSE:
EndDialog(hDlg, LOWORD(wParam));
break;
}
return DefWindowProc(hDlg, message, wParam, lParam);
}
Modal dialogs are similar to MessageBox: your code gets control back when the dialog is closed. API: DialogBox, DialogBoxIndirect.
Modeless dialogs are similar to windows: you create them with the help of dialog templates and you get the control back immediately, they live powered by message dispatch. This is what you do but you expect them to act as if they were modal. API: CreateDialog, CreateDialogIndirect.
With both modal and modeless dialog you control the dialog with your own DialogProc and you create the dialog with resource dialog template, which automatically creates controls (and you, of course, can add control in code).
I know the way window is created when the app is windowed one from the start, that is you call
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
int WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int nCmdShow);
But what to do if I want to get user an option to display a console application output when it ends. That is display its data in more readable form in ad-hoc created window instead of text-only mode that console permits.
In console app I have a function that watches for user key press, and when my program ends it shows message: press D to display result in a window instead of console, and in code:
if (virtual_key == 0x44) {
HWND myWindow = myCreateWindFunc(/* data */);
}
That is I need to pack all the code for creating window into one function an then just call function on it with the data to fill it's controlls.
A console application can create child windows or dialog boxes using any related WinAPI function (MessageBox, DialogBox etc).
The only caveat is that the create function may require the handle of the console window. To obtain it, you could use the example here How To Obtain a Console Window Handle
I am attempting to learn about creating windows in c++, I have looked at an article about creating a wrapper class but I don't really understand it. So far I know that you can't have a class method WndProc (I dont know why) but honestly, that is all. Can somebody give an explanation, also explaining the reinterpret_cast? Here is the article.
LRESULT CALLBACK Window::MsgRouter(HWND hwnd, UINT message,
WPARAM wparam, LPARAM lparam)
{
Window *wnd = 0;
if(message == WM_NCCREATE)
{
// retrieve Window instance from window creation data and associate
wnd = reinterpret_cast<Window *>((LPCREATESTRUCT)lparam)->lpCreateParams;
::SetWindowLong(hwnd, GWL_USERDATA, reinterpret_cast<long>(wnd));
// save window handle
wnd->SetHWND(hwnd);
}
else
// retrieve associated Window instance
wnd = reinterpret_cast<Window *>(::GetWindowLong(hwnd, GWL_USERDATA));
// call the windows message handler
wnd->WndProc(message, wparam, lparam);
}
Thanks in advance, ell.
The MsgRouter() procedure acts as a proxy between the Windows message handling system to the Window instance associated with a HWND. It routes Windows messages to C++ objects.
A pointer to the Window instance is passed to the MsgRouter() procedure via the last parameter of the CreateWindow() function. When you first create a HWND via CreateWindow() (or CreateWindowEx()), some messages are sent - one of them being WM_NCCREATE. When the procedure receives a WM_NCCREATE message, the LPARAM parameter contains a pointer to a CREATESTRUCT which contains the arguments that was passed into the CreateWindow() function. The procedure retrieves the Window instance pointer from the CREATESTRUCT and saves it in the HWND by setting it as an attribute of the HWND (GWL_USERDATA via SetWindowLong()).
Now that the pointer has been saved, the window procedure can from now on retrieve a pointer to the original Window instance from a HWND via GetWindowLong() when it receives a message. Finally, the window procedure calls WndProc() on the retrieved Window pointer, passing in the exact message and parameters, so the Window instance can handle the message.