スクリーンセーバーを作成する


スクリーンセーバーとして動作するアプリケーションには scrnsave.h をインクルードして、scrnsavw.lib をリンクしておきます。
(マルチバイト文字セットでコンパイル場合は scrnsave.lib をリンクしてください)
ScreenSaverProc がスクリーンセーバーのメイン関数になります。
コンパイル後の出力ファイルの拡張子は scr にします。


Sample code
#include <windows.h>
#include <scrnsave.h>

#ifdef UNICODE
#pragma comment(lib, "scrnsavw.lib")
#else
#pragma comment(lib, "scrnsave.lib")
#endif
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "comctl32.lib")

#define WM_USER_TIMER WM_USER + 1

void CALLBACK TimeProc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);

LONG timerFlag = 0;

//スクリーンセーバーメイン関数
LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static UINT timer;
    
    switch (message) {
        case WM_CREATE:
            {
                //タイマー設定
                timeBeginPeriod(1);
                timer = timeSetEvent(100, 1, TimeProc, reinterpret_cast<DWORD_PTR>(hWnd), TIME_PERIODIC);
            }
            break;
        case WM_ERASEBKGND:
            break;
        case WM_PAINT:
            {
                PAINTSTRUCT ps;
                BeginPaint(hWnd, &ps);
                //TODO: ここに描画処理を記述します。
                
                EndPaint(hWnd, &ps);
            }
            break;
        case WM_USER_TIMER:
            {
                //TODO: ここにタイマー処理を記述します。
                
                //再描画
                InvalidateRect(hWnd, NULL, FALSE);
                InterlockedExchange(&timerFlag, 0);
            }
            break;
        case WM_DESTROY:
            {
                //タイマー破棄
                timeKillEvent(timer);
                timeEndPeriod(1);
            }
            break;
        default:
            return DefScreenSaverProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

void CALLBACK TimeProc(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR)
{
    if(InterlockedExchange(&timerFlag, 1) == 0) {
        PostMessage(reinterpret_cast<HWND>(dwUser), WM_USER_TIMER, static_cast<WPARAM>(uTimerID), 0);
    }
}

BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
    UNREFERENCED_PARAMETER(hInst);
    return TRUE;
}

//スクリーンセーバー設定ダイアログボックス
//(ダイアログの ID は scrnsave.h の DLG_SCRNSAVECONFIGURE)
BOOL WINAPI ScreenSaverConfigureDialog(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    
    switch (message) {
        case WM_COMMAND:
            {
                switch (LOWORD(wParam)) {
                    case IDOK:
                        EndDialog(hWnd, IDOK);
                        break;
                    case IDCANCEL:
                        EndDialog(hWnd, IDCANCEL);
                        break;
                    default:
                        return FALSE;
                        break;
                }
            }
            break;
        default:
            return FALSE;
            break;
    }
    return TRUE;
}

一覧メニューへ