I am making an program and would like to have my program restarted when a person tries to resize the screen.
So far from searching the internet i've found that it's not possible to ''re-run your application'' as with code.
Everyone refers to just close and rerun it, but that's not what i want, i want the code to be doing that.
So i was thinking, can i not re-run winmain? and ' kill ' the current winmain instance in my code, but keep the ''shell (application?)'' active?
this is what i am trying to do:
LRESULT CALLBACK Proc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_SIZE: //Check if the window has been resized
WinMain(this, this, this, NULL);
// or restart application code.
break;
case WM_PAINT: // we need to paint? lets paint!
if (DrawUI)
Render(true);
else
Render(false);
break;
case WM_CREATE:
return DwmExtendFrameIntoClientArea(hWnd, &pMargin); // extension of window frame into client area
break;
case WM_DESTROY:
PostQuitMessage(0); // We need to use this to exit a message loop
break;
default:
return DefWindowProc(hWnd, Message, wParam, lParam); // Making sure all messages are processed
break;
}
}
please see the code under WM_SIZE: that's what im trying to do, but i don't know how to do this correctly, and how to close the previous winmain.
Related
my application is running in Background completely but shows it's activity via a notification icon in system tray. Now I wanted to add a popup-menu to that notification icon. Unfortunately I do not receive any events from it. That's what I'm doing currently to create the icon and its event handler:
First create an invisible window to use it's event handler
ZeroMemory(&wc,sizeof(WNDCLASSEX));
wc.cbSize=sizeof(WNDCLASSEX);
wc.lpfnWndProc=WndProc;
wc.hInstance=hInstance;
wc.lpszClassName=L"myCL";
RegisterClassEx(&wc);
hWnd=CreateWindowEx(WS_EX_CLIENTEDGE,L"myCL",L"myWN",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,
CW_USEDEFAULT,1,1,NULL,NULL,hInstance,NULL);
Next create and show the icon itself:
ZeroMemory(&niData,sizeof(NOTIFYICONDATA));
niData.cbSize=sizeof(NOTIFYICONDATA);
niData.uID=IDI_AAAA; // the icon's identifier
niData.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
niData.hIcon=(HICON)LoadImage(hInstance,MAKEINTRESOURCE(IDI_AAAA),IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),
LR_DEFAULTCOLOR);
niData.hWnd=hWnd;
niData.uCallbackMessage=MY_TRAY_ICON_MESSAGE;
Shell_NotifyIcon(NIM_ADD,&niData);
And the event handler that is assigned to the invisible window and where I would have assumed the events from the icon should arrive too:
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case MY_TRAY_ICON_MESSAGE: // this should be related to notification icon but is never called
switch (lParam)
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_CONTEXTMENU:
break;
}
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0;
}
Anybody an idea what is wrong here?
I've read everywhere that using windows messages is preferable to DirectInput. Despite this, there are many DirectInput tutorials and barely any for dealing with keyboard in Windows messaging. After not finding any good sources, I began to try it on my own.
I made two 256 member bool arrays to hold if keys were pressed. I want to make it so that I can look at m_bKeyDown[256] to see if a key was pressed this frame, and m_bKeyDown to see if it is being held down, but not pressed this frame. My MsgProc switch statement is as follows:
LRESULT D3DApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
if(m_bKeyPressed[wParam])
m_bKeyDown[wParam] = false;
else
m_bKeyDown[wParam] = true;
break;
m_bKeyPressed[wParam] = true;
case WM_KEYUP:
m_bKeyDown[wParam] = false;
m_bKeyPressed[wParam] = false;
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
I tested it by having it make a sound when I held down the F1 key. Ideally the sound should not repeat until I release the button and press it again:
if(m_bKeyDown[VK_F1])
m_fMod.FPlaySound(testSound);
There seems to be no difference though, the sound repeats when I hold down the button. How do I fix the loop or set up Windows messaging to do this? Am I on the right track or should I go a completely different direction?
Edit: I used iedoc's below example and now it does better, but the sound still plays three times before stopping, like there is a delay for some reason. Any idea how to avoid this?
try this:
LRESULT D3DApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
if(!m_bKeyPressed[wParam])
{
m_bKeyDown[wParam] = true;
m_bKeyPressed[wParam] = true;
}
else
m_bKeyDown[wParam] = false;
break;
case WM_KEYUP:
m_bKeyDown[wParam] = false;
m_bKeyPressed[wParam] = false;
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
I use WM_MBUTTONDOWN to keep track of middle mouse button when it's pressed. So, when I click the middle mouse button at the mouse wheel, it will display the message on the console. I wonder why it doesn't work. Is WM_MBUTTONDOWN for another usage?
LRESULT CALLBACK UI::WindowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
// The message is post when we destroy the window.
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_MBUTTONDOWN:
cout << "Middle button clicked" << endl;
break;
// Default handling for other messages.
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Output:
Mouse used: Logitech
This looks like a driver issue. On some mice WM_MBUTTONDOWN message is not received. Make sure you use a mouse driver that supports middle button.
Check if the middle button works in other applications - if not, it is a driver issue.
I'm using Windows 7 and VC++. The business is to know how many seconds my system has been set into screen saver mode or monitor screen off. To achieve this, I'm trying to catch the events WM_SYSCOMMAND and SC_SCREENSAVE, SC_MONITORPOWER. So I have created a Win32 project in Visual Studio 2008 and I'm receiving the events in WndProc function:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_SYSCOMMAND:
{
switch (LOWORD(wParam))
{
case SC_SCREENSAVE:
{
FILE *fl = fopen("this_is_a_event_test.txt","a");
fputs("SC_SCREENSAVE\n",fl);
fclose(fl);
}
break;
case SC_MONITORPOWER:
{
FILE *fl = fopen("this_is_a_event_test.txt","a");
fputs("SC_MONITORPOWER\n",fl);
fclose(fl);
}
break;
default:
{
}
}
}
break;
}
}
It works fine when dialog is in foreground, but in background (or if I comment ShowWindow function) it only works if I manually send the events:
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_SCREENSAVE, (LPARAM)2);
or
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2);
So, it is not working when system power configuration sets the screen saver after 2 minutes of inactivity, and the same thing with automatic monitor screen off. Thats the real thing I want, know when the system is turning off the screen or setting the screen saver, with a background monitoring program.
I have also tried to use hook events with extern dll. I have followed this example http://www.codeproject.com/Articles/1037/Hooks-and-DLLs adding in the CALLBACK msghook() function the same switch code above in WndProc. It doesn't work even using the SendMessage.
After several days stuck with this issue, searching in the Internet, forums... I don't know what else I can do. Can anyone help me?
I were not using hooks properly, but it has been rare. Firstly, about setWindowsHookEx function, I have read WH_CALLWNDPROC or WH_SYSMSGFILTER must be used to get WM_SYSCOMMAND sent messages, and then get SC_SCREENSAVE wParam. In this case, I don't know why and maybe I'm wrong, but thats seems not to be true.
After use every possible message to SetWindowsHookEx, I realised WH_GETMESSAGE is the only one who sends SC_SCREENSAVE wParam, at least in this hook example in Windows 7.
HHOOK hook;
HHOOK hook = SetWindowsHookEx(WH_GETMESSAGE,
(HOOKPROC)msghook,
hInst,
0);
Secondly, listening for every message catched in hook function, WM_SYSCOMMAND were appeared with LPMSG. I have read also that wParam must to be combined to 0xFFF0 to be compared. But wParam & 0xFFF0 == SC_SCREENSAVE didn't work and wParam == SC_SCREENSAVE neither. In this case the only way is using LPMSG for both WM_SYSCOMMAND and SC_SCREENSAVE.
static LRESULT CALLBACK msghook(UINT code, WPARAM wParam, LPARAM lParam)
{
if(code > 0)
{
CallNextHookEx(hook, code, wParam, lParam);
return 0;
}
LPMSG msg = (LPMSG)lParam;
if(msg->message == WM_SYSCOMMAND)
{
if (msg->wParam == SC_SCREENSAVE)
{
MessageBoxA(NULL,L"SC_SCREENSAVE",L"SC_SCREENSAVE",MB_OK);
}
if (msg->wParam == SC_MONITORPOWER)
{
MessageBoxA(NULL,L"SC_MONITORPOWER",L"SC_MONITORPOWER",MB_OK);
}
}
return CallNextHookEx(hook, nCode, wParam, lParam);
}
And using FILE to test the events was a very bad idea, I think using MessageBox is not much better but I don't know how to test ir correctly.
I am currently trying to grab all of the user input to the windows calculator app. It seems the way to do this is to use Win32 to intercept all of the keyboard and mouse inputs that are intended for the calculator window. I have read the MSDN page on subclassing a window at the link below and have done some research on subclassing.
I have the syntax for subclassing a window, but I am not sure how to tell the program which window I am looking to subclass.
the code that I have so far is listed below. My problem right now is that I am not sure how the variable "hWndEdit" is assigned. I am pretty new to Win32 programming so any help is appreciated.
(link)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633570(v=vs.85).aspx
WNDPROC wpOrigEditProc;
wpOrigEditProc = (WNDPROC) SetWindowLong(hWndEdit,GWL_WNDPROC,(long) WndEditProc);
LRESULT CALLBACK WndEditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CHAR:
case WM_KEYUP:
case WM_KEYDOWN:
if (hWnd == hWndEdit)
return 0;
break;
case WM_DESTROY:
// Remove the subclass from the edit control.
SetWindowLong(hWndEdit, GWL_WNDPROC, (LONG) wpOrigEditProc);
break;
default:
return CallWindowProc((WNDPROC ) wpOrigEditProc, hWnd, message, wParam, lParam);
}
return CallWindowProc((WNDPROC ) wpOrigEditProc, hWnd, message, wParam, lParam);
}
To find a window, first use Spy++ (A tool that gets installed with Visual Studio) to find the class name and the window name of the calculator main window. Then, in your application, use the FindWindow API:
hWndEdit = FindWindow(className, windowName);
Although, I'm not sure that subclassing is the right method here since the Calculator window is not owned by your application. You should do this with hooks.