Jpsarapuu
July 15th, 2008, 01:20 PM
Hi!
I am trying to make a Hello World program with little more features than usual.
I wanted it to allow running of only one instance of the program. This part was
OK. The problem came when I wanted it to hide/show itself with one key
press. The program hides itself correctly and runs in background but I can't get it back active. Also, I don't want this program to occupy 50% of CPU
Usage. What am I doing wrong?
Here's the code:
#include <windows.h>
#include <ctime>
#include "Resource.h"
HWND MainWindow = 0;
bool InitializeApp(HINSTANCE hInstance, HWND hwnd, int nShowCmd);
int Run();
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
HANDLE hMutex = CreateMutex(NULL, FALSE, "APPLICATION_ID");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
::MessageBox(0, "Program is already running!", "Error", MB_OK);
return 0;
}
if(!InitializeApp(hInstance, MainWindow, nShowCmd))
{
::MessageBox(0, "Initialization Failed!", "Error", MB_OK);
return 0;
}
return Run();
}
bool InitializeApp(HINSTANCE hInstance, HWND hWnd, int nShowCmd)
{
WNDCLASSEX wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = ::LoadIcon(hInstance, MAKEINTRESOURCE(WINDOWICON));
wc.hIconSm = ::LoadIcon(hInstance, MAKEINTRESOURCE(WINDOWICON));
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
wc.lpszMenuName = 0;
wc.lpszClassName = "HWC"; // Hello World Class
if(!::RegisterClassEx(&wc))
{
::MessageBox(0, "WNDCLASS registration failed!", "Error", 0);
return false;
}
UINT XPOS = (::GetSystemMetrics(SM_CXSCREEN) - WIDTH) / 2;
UINT YPOS = (::GetSystemMetrics(SM_CYSCREEN) - HEIGHT) / 2;
MainWindow = ::CreateWindow(
"HWC",
"Hello, World!",
WS_OVERLAPPEDWINDOW,
XPOS, // Place window in the middle of the screen
YPOS,
WIDTH,
HEIGHT,
0,
0,
hInstance,
0);
if(MainWindow == 0)
{
::MessageBox(0, "Window creation failed!", 0, 0);
return false;
}
::ShowWindow(MainWindow, nShowCmd);
::UpdateWindow(MainWindow);
return true;
}
int Run()
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
while(TRUE)
{
long int startpoint = ::GetTickCount();
if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
if(msg.message == WM_KEYDOWN)
{
if(msg.wParam == VK_DELETE)
{
::ShowWindow(MainWindow, SW_HIDE);
::UpdateWindow(MainWindow);
}
if(msg.wParam == VK_SPACE)
{
::ShowWindow(MainWindow, SW_SHOW);
::UpdateWindow(MainWindow);
}
if(msg.wParam == VK_ESCAPE)
{
::DestroyWindow(MainWindow);
}
}
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
while((::GetTickCount() - startpoint) < 25);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_LBUTTONDOWN:
::MessageBox(0, "Hello, World!", "Hello!", MB_OK);
return 0;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}
PS. Don't mind the Resource header, it's for the icons that work fine.
I am trying to make a Hello World program with little more features than usual.
I wanted it to allow running of only one instance of the program. This part was
OK. The problem came when I wanted it to hide/show itself with one key
press. The program hides itself correctly and runs in background but I can't get it back active. Also, I don't want this program to occupy 50% of CPU
Usage. What am I doing wrong?
Here's the code:
#include <windows.h>
#include <ctime>
#include "Resource.h"
HWND MainWindow = 0;
bool InitializeApp(HINSTANCE hInstance, HWND hwnd, int nShowCmd);
int Run();
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
HANDLE hMutex = CreateMutex(NULL, FALSE, "APPLICATION_ID");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
::MessageBox(0, "Program is already running!", "Error", MB_OK);
return 0;
}
if(!InitializeApp(hInstance, MainWindow, nShowCmd))
{
::MessageBox(0, "Initialization Failed!", "Error", MB_OK);
return 0;
}
return Run();
}
bool InitializeApp(HINSTANCE hInstance, HWND hWnd, int nShowCmd)
{
WNDCLASSEX wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = ::LoadIcon(hInstance, MAKEINTRESOURCE(WINDOWICON));
wc.hIconSm = ::LoadIcon(hInstance, MAKEINTRESOURCE(WINDOWICON));
wc.hCursor = ::LoadCursor(0, IDC_ARROW);
wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
wc.lpszMenuName = 0;
wc.lpszClassName = "HWC"; // Hello World Class
if(!::RegisterClassEx(&wc))
{
::MessageBox(0, "WNDCLASS registration failed!", "Error", 0);
return false;
}
UINT XPOS = (::GetSystemMetrics(SM_CXSCREEN) - WIDTH) / 2;
UINT YPOS = (::GetSystemMetrics(SM_CYSCREEN) - HEIGHT) / 2;
MainWindow = ::CreateWindow(
"HWC",
"Hello, World!",
WS_OVERLAPPEDWINDOW,
XPOS, // Place window in the middle of the screen
YPOS,
WIDTH,
HEIGHT,
0,
0,
hInstance,
0);
if(MainWindow == 0)
{
::MessageBox(0, "Window creation failed!", 0, 0);
return false;
}
::ShowWindow(MainWindow, nShowCmd);
::UpdateWindow(MainWindow);
return true;
}
int Run()
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
while(TRUE)
{
long int startpoint = ::GetTickCount();
if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
if(msg.message == WM_KEYDOWN)
{
if(msg.wParam == VK_DELETE)
{
::ShowWindow(MainWindow, SW_HIDE);
::UpdateWindow(MainWindow);
}
if(msg.wParam == VK_SPACE)
{
::ShowWindow(MainWindow, SW_SHOW);
::UpdateWindow(MainWindow);
}
if(msg.wParam == VK_ESCAPE)
{
::DestroyWindow(MainWindow);
}
}
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
while((::GetTickCount() - startpoint) < 25);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_LBUTTONDOWN:
::MessageBox(0, "Hello, World!", "Hello!", MB_OK);
return 0;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}
PS. Don't mind the Resource header, it's for the icons that work fine.