0

I'm trying to make a screenshot helper that takes screenshots when it receives signal from other application. In my design, the higher layer application will send a window message to the helper, and the helper will then take a screenshot for user (by simulating Win+Prtsc). I've done this without any problem, but when I try to add a feature that implements by detecting the gap between two message, I found that GetMessageTime() function works weird.

The problem is that I added a MessageBox for debugging, and GetMessageTime returns the proper ticks the message was sent at. But when I removed that MessageBox, GetMessageTime kept returning 0. I searched the web and MSDN documents but found nothing about this. So I'm just wondering what happened and what should I do, without changing the architecture that using HWND_MESSAGE window to receive message.

MessageReceiver

#include <Windows.h>
#include <stdio.h>

HWND hwndMain;
UINT hotkeyTriggeredMessageId;
INPUT winPlusPrtscKeyCombo[4];
LONG lastHotkeyTime = -1000;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    if (message == hotkeyTriggeredMessageId) {
        printf("last:%d,this:%d,diff:%d\n", lastHotkeyTime, GetMessageTime(), lastHotkeyTime - GetMessageTime());
        MessageBox(NULL, L"triggered!", L"", NULL);
        printf("last:%d,this:%d,diff:%d\n", lastHotkeyTime, GetMessageTime(), lastHotkeyTime - GetMessageTime());
        SendInput(4, winPlusPrtscKeyCombo, sizeof(INPUT));
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

int main() {
    MSG msg;
    BOOL bRet;
    WNDCLASS wc = { 0 };
    memset(winPlusPrtscKeyCombo, 0, sizeof(INPUT) * 4);
    winPlusPrtscKeyCombo[0].type = INPUT_KEYBOARD;
    winPlusPrtscKeyCombo[0].ki.wVk = VK_LWIN;
    winPlusPrtscKeyCombo[1].type = INPUT_KEYBOARD;
    winPlusPrtscKeyCombo[1].ki.wVk = VK_SNAPSHOT;
    winPlusPrtscKeyCombo[2].type = INPUT_KEYBOARD;
    winPlusPrtscKeyCombo[2].ki.wVk = VK_SNAPSHOT;
    winPlusPrtscKeyCombo[2].ki.dwFlags = KEYEVENTF_KEYUP;
    winPlusPrtscKeyCombo[3].type = INPUT_KEYBOARD;
    winPlusPrtscKeyCombo[3].ki.wVk = VK_LWIN;
    winPlusPrtscKeyCombo[3].ki.dwFlags = KEYEVENTF_KEYUP;
    HINSTANCE hInstance = GetModuleHandle(NULL);
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = L"MessageReceiverWindow";
    if (!RegisterClass(&wc)) {
        return FALSE;
    }
    hwndMain = CreateWindow(L"MessageReceiverWindow", L"MessageReceiverWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hInstance, 0);
    hotkeyTriggeredMessageId = RegisterWindowMessage(L"MESSAGE_HOTKEY_TRIGGERED");
    ChangeWindowMessageFilterEx(hwndMain, hotkeyTriggeredMessageId, MSGFLT_ALLOW, NULL);
    UpdateWindow(hwndMain);
    while (GetMessage(&msg, NULL, 0, 0)) {
        DispatchMessage(&msg);
    }
    return 0;
}

MessageSender

#include <stdio.h>
#include <Windows.h>

UINT hotkeyTriggeredMessageId;
HWND targetWindow;

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) {
    hotkeyTriggeredMessageId = RegisterWindowMessage(L"MESSAGE_HOTKEY_TRIGGERED");
    targetWindow = FindWindowEx(HWND_MESSAGE, NULL, L"MessageReceiverWindow", NULL);
    SendMessage(targetWindow, hotkeyTriggeredMessageId, NULL, NULL);
    return 0;
}
June
  • 1
  • 1
  • 1
    [`GetMessageTime`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessagetime) doesn't take any arguments. It rather *"retrieves the message time for the last message retrieved by the `GetMessage` function"*. If your thread doesn't retrieve any messages, then there is no meaningful time to report. If you show a message box, the system spins up a message loop, and things miraculously start working. – IInspectable Nov 13 '22 at 13:13
  • But I have set up a message loop in the main function and `WndProc` was called as expected. When I send message using `MessageSender`, it also retrieves the registered message properly. Is the caller thread of `GetMessageTime` affects? How can I call `GetMessageTime` in `MessageReceiverWindow`'s thread? @IInspectable – June Nov 14 '22 at 02:58
  • Well I think I've made myself understand all these strange things. Is it mean the `GetMessageTime`'s return value is actually from the message box that just generated? And in this thought, `GetMessageTime` of custom message is merely returning 0 and the function is just doing the right thing. I think I'm going to pass the triggered time in `wParam` then... – June Nov 14 '22 at 09:20

0 Answers0