Událostmi řízená aplikace (WinAPI)

#include <windows.h> #include <stdio.h> #include <string.h> // Global variables HINSTANCE hInst; UINT uMyMsgWndMoving; HINSTANCE mhInst; HWND mhWnd; // handle to own window (initialize in WinMain) HDC mhDC; // device context (initialize in each Paint function calling) // Function prototypes. int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int); LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM); void onPaint(HWND hWnd); BOOL CALLBACK PrintEnumWindowsProc(HWND hWnd,LPARAM lParam); // Application entry point. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; BOOL bRet; WNDCLASS wcx; // register class hInst = hInstance; // Save the application-instance handle. uMyMsgWndMoving = RegisterWindowMessage("MyMessage"); // Fill in the window class structure with parameters that describe the main window. wcx.style = CS_HREDRAW | CS_VREDRAW; // redraw if size changes wcx.lpfnWndProc = (WNDPROC) MainWndProc; // points to window procedure wcx.cbClsExtra = 0; // no extra class memory wcx.cbWndExtra = 0; // no extra window memory wcx.hInstance = hInstance; // handle to instance wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); // predefined app. icon wcx.hCursor = LoadCursor(NULL, IDC_ARROW); // predefined arrow wcx.hbrBackground = GetStockObject(WHITE_BRUSH); // white background brush wcx.lpszMenuName = (LPCSTR) "MainMenu"; // name of menu resource wcx.lpszClassName = (LPCSTR) "ITUClass"; // name of window class // Register the window class. if (!RegisterClass(&wcx)) { return FALSE; } // create window of registered class mhWnd = CreateWindow("ITUClass", "ITU", WS_OVERLAPPEDWINDOW, 0, 0, 200, 200, (HWND) NULL, (HMENU) NULL, hInstance, (LPVOID) NULL); if (!mhWnd) { return FALSE; } // Show the window and send a WM_PAINT message to the window procedure. // Record the current cursor position. ShowWindow(mhWnd, nCmdShow); UpdateWindow(mhWnd); while ((bRet = GetMessage(&msg, NULL, 0, 0 )) != 0) { if (bRet == -1) { // handle the error and possibly exit } else { TranslateMessage(&msg); DispatchMessage(&msg); } } PostMessage(HWND_BROADCAST, uMyMsgWndMoving, 0, 0); return (int) msg.wParam; } LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { InvalidateRect(hWnd, NULL, 0); // Some of the application instance is moving if (uMsg == uMyMsgWndMoving) { InvalidateRect(hWnd, NULL, 1); return 0; } switch (uMsg) { case WM_CREATE: // Initialize the window. return 0; case WM_SIZE: // Set the size and position of the window. PostMessage(HWND_BROADCAST, uMyMsgWndMoving, 0, 0); return 0; case WM_MOVE: // Set the new window position. (Send it to all application instances.) PostMessage(HWND_BROADCAST, uMyMsgWndMoving, 0, 0); return 0; case WM_PAINT: // Paint the window's client area. onPaint(hWnd); return 0; case WM_DESTROY: // Clean up window-specific data objects. PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } } void onPaint(HWND hWnd) { PAINTSTRUCT ps; // information can be used to paint the client area of a window owned by that application mhDC = BeginPaint(hWnd, &ps); // prepares the specified window for painting (use global variable) EnumWindows(&PrintEnumWindowsProc, 0); // process PrintEnumWindowsProc function to all existed windows DeleteDC(mhDC); // deletes the specified device context EndPaint(hWnd, &ps); // marks the end of painting in the specified window } BOOL CALLBACK PrintEnumWindowsProc(HWND hWnd, LPARAM lParam) { char WClassName[256]; char mWClassName[256]; RECT myRect, otherRect; GetClassName(hWnd, WClassName, 256); // get class name of some system window GetClassName(mhWnd, mWClassName, 256); // get class name of your own window if ((strcmp(WClassName, mWClassName) == 0) && (hWnd != mhWnd)) { GetWindowRect(mhWnd, &myRect); GetWindowRect(hWnd, &otherRect); int myX = (myRect.right - myRect.left) / 2; int myY = (myRect.bottom - myRect.top) / 2; int otherX = otherRect.left - myRect.left + (otherRect.right - otherRect.left) / 2; int otherY = otherRect.top - myRect.top + (otherRect.bottom - otherRect.top) / 2; MoveToEx(mhDC, myX, myY, NULL); LineTo(mhDC, otherX, otherY); } return TRUE; }