// 99/07/01 by SANE // sane@eastmail.com #include #include #include // アプリケーションネームを定義。 char szAppName[] = "dcs"; // クラスネームを定義。 char szClassName[] = "dcs Class"; HINSTANCE hInst = NULL; HWND hMainWnd = NULL; // タイマーを10ms毎にする。 DWORD TimerID=NULL,Timer=10; int cx,cy; LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); void CALLBACK TimerFunc( UINT wID, UINT uMsg, DWORD dwUser,DWORD w1,DWORD w2); void StartTimer(); void StopTimer(); void RestoreWindow(); int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; MSG msg; HDC hdc; if (FindWindow(szClassName,szAppName) != NULL) { // 2重実行防止処理 return 0; } // クラスを定義する。 hInst = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = NULL; wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = szClassName; if(!RegisterClass(&wc)) return FALSE; // HWND ハンドルを取得するためにウィンドウを作る。 hMainWnd = CreateWindowEx( 0, szClassName, szAppName, WS_OVERLAPPEDWINDOW, 0, 0, 1, 1, NULL, NULL, hInstance, NULL); // デスクトップの解像度を取得する。 hdc = GetWindowDC(NULL); cx = GetDeviceCaps(hdc,HORZRES); cy = GetDeviceCaps(hdc,VERTRES); ReleaseDC(hMainWnd,hdc); // タイマースタート StartTimer(); // CTRLキーの初期化 GetAsyncKeyState(VK_CONTROL); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // タイマー停止 StopTimer(); // 全てのウインドウを描きなおす。 RestoreWindow(); // プログラムの終了。 return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_TIMER: { HDC hdc; // デスクトップのDeviceContextを取得し、 // 直接描けるようにする。 if ((hdc = GetWindowDC(NULL)) != NULL) { POINT point; int xr,xw; xr = rand()%cx*2-cx; xw = rand()%cx; // "xr"から幅"xw"だけ下に崩す。 BitBlt(hdc,xr,1,xw,cy,hdc,xr,0,SRCCOPY); // 崩した後、上部を黒く塗りつぶす。 SelectObject(hdc,GetStockObject(BLACK_BRUSH)); MoveToEx(hdc,xr,0,&point); LineTo(hdc,xr+xw,0); ReleaseDC(hMainWnd,hdc); } if (GetAsyncKeyState(VK_CONTROL) != 0) { // CTRLキーが押されたら終了。 PostMessage(hMainWnd,WM_CLOSE,0,0); } break; } case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } void RestoreWindow() { // 全てのウインドウを描きなおす。 InvalidateRect(NULL,NULL,false); return; } void CALLBACK TimerFunc( UINT wID, UINT uMsg, DWORD dwUser,DWORD w1,DWORD w2) { // タイマーが呼び出されるたびにWM_TIMERを送る。 PostMessage(hMainWnd,WM_TIMER,0,0); return; } void StartTimer() { TIMECAPS caps; // 高精度タイマーを取得する。 timeGetDevCaps( &caps,sizeof(caps) ); timeBeginPeriod( caps.wPeriodMin ); TimerID = timeSetEvent(Timer,caps.wPeriodMin,TimerFunc,0,(UINT)TIME_PERIODIC); return; } void StopTimer() { TIMECAPS caps; // 取得した高精度タイマーを破棄する。 timeKillEvent(TimerID); TimerID=NULL; timeGetDevCaps( &caps,sizeof(caps) ); timeEndPeriod( caps.wPeriodMin ); return; }