簡體   English   中英

為什么我不能在 settimer 中將靜態轉換的 Lambda 轉換為 TIMEPROC Function 指針?

[英]Wy can't I cast a statically cast Lambda as a TIMEPROC Function pointer in a settimer?

我多次編碼。 但它甚至似乎不適用於簡單的控制台 hello word 應用程序。 hWND 是罪魁禍首,lambda,還是 lambda 的鑄件?

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "Windows.h"
void sleeper()
{
    Sleep(10000);
}
int main()
{
    SetTimer
    (GetConsoleWindow(), 1, 1000, [](HWND, UINT, UINT_PTR, DWORD)
        {
        printf("Hello World!");
        }
    );
    sleeper();
    return 0;
}

它沒有給我警告。

您不能將lamba 強制轉換為TIMEPROC* 或任何其他類型的function 指針,這些指針使用與默認不同的調用約定(不能指定lambda 的調用約定)。 Lambda 是可調用的對象。 此類型類似於 class,具有成員 function。

除此之外,您必須為您的 TIMERPROC 掛鈎使用正確的聲明。 這是:

// definition from the MS website.  It is incomplete (typical from MS)
// ref: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-timerproc
void Timerproc(
  HWND unnamedParam1,
  UINT unnamedParam2,
  UINT_PTR unnamedParam3,
  DWORD unnamedParam4
)

// the actual definition from winuser.h.
typedef VOID (CALLBACK* TIMERPROC)(HWND, UINT, UINT_PTR, DWORD):

// note the use of CALLBACK, which expands to __stdcall.  That's the very important 
// detail missing from the actual documentation.

You can declare your timeproc as a free-standing function, or as a static member function of a class, Unfortunately the onluy parameter you can pass to the callback is a HWND, this means that if you want to pass any extra parameter to your callback ,您必須使用 static(又名全局)變量。

示例 1。

void CALLBACK myTimerProc(HWND, UINT, UINT_PTR, DWORD)
{
   printf("Hello World!");
}

int main()
{
    // NOTE nIDEvent, the timer ID has to be unique for the window and NON-ZERO,
    // See MS documentation here: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer
    SetTimer(GetConsoleWindow(), 1, 1000, myTimerProc);
    sleeper();
    return 0;
}

Example2,如果要在本地定義:

int main()
{
    struct local // or any other 
    {
        static void CALLBACK timerProc(HWND, UINT, UINT_PTR, DWORD)
        {
            printf("Hello World!");
        }
    }

    SetTimer(GetConsoleWindow(), 1, 1000, local::timerProc);
    sleeper();
    return 0;
}

編輯:作為參考,TIMERPROC 回調的實際參數。

資料來源: http://www.icodeguru.com/VC%26MFC/MFCReference/html/_mfc_cwnd.3a3a.settimer.htm

void CALLBACK EXPORT TimerProc(
   HWND hWnd,      // handle of CWnd that called SetTimer
   UINT nMsg,      // WM_TIMER
   UINT nIDEvent   // timer identification
   DWORD dwTime    // system time
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM