【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

二重起動禁止と通知

昨日C#で作ったものと同じようなものをC言語で実装してみました。二重起動判定はMutexではなくFindWindow()で行っています。なるべく簡単に実装するため、.NETリモーティングの代わりにWM_SETTEXTを投げています。

#include <windows.h>
#include <tchar.h>
    
WNDPROC DefWndProc;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(
    HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    int ret = 0;
    HWND hWnd = FindWindow(NULL, TEXT("SingleApp Test"));
    if (hWnd == NULL)
    {
        hWnd = CreateWindow(TEXT("LISTBOX"), TEXT("SingleApp Test"),
            WS_OVERLAPPEDWINDOW | LBS_STANDARD,
            CW_USEDEFAULT, 0, 200, 200, NULL, NULL, hInstance, NULL);
        if (hWnd)
        {
            MSG msg;
            DefWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LPARAM)WndProc);
            ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
            while (GetMessage(&msg, NULL, 0, 0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            ret = msg.wParam;
        }
    }
    else
    {
        TCHAR buf[64];
        wsprintf(buf, TEXT("call: %d"), GetTickCount());
        SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)buf);
    }
    return ret;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_SETTEXT:
        SendMessage(hWnd, LB_ADDSTRING, 0, lParam);
        SendMessage(hWnd, LB_SETCURSEL, SendMessage(hWnd, LB_GETCOUNT, 0, 0) - 1, 0);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return CallWindowProc(DefWndProc, hWnd, message, wParam, lParam);
}