问题
So I was making a function to print text layered across a different window, and I wanted it to be in a separate thread so I can run a timer for the text to display while leaving the user open to continue using the program. However, when I compile I get this error:
error C2664: '_beginthreadex' : cannot convert parameter 3 from 'overloaded-function' to 'unsigned int (__stdcall *)(void *)'
Here's the main cpp file:
#include "stdafx.h"
#include "Trial.h"
int main()
{
wchar_t* text = L"Message!";
HWND hwnd = FindWindowW(0, L"Halo");
unsigned threadID;
_beginthreadex(0, 0, DrawText,(void *)(hwnd, 175, 15, text, 8), 0 , &threadID);
// Other function here
}
And here's the header file Trial.h: (it's a little sloppy, but works fine and since most monitors are around 2ms updates, sleep(2) should help prevent flicker).
#pragma once
#include <Windows.h>
#include <string>
#include <process.h>
void DrawText(HWND hWnd, float x, float y, wchar_t* mybuffer, float DisplayTime)
{
SetForegroundWindow(hWnd);
HDC hdc = GetDC(hWnd);
SetBkColor(hdc,RGB(255, 255, 255)); // While Background color...
SetBkMode(hdc, TRANSPARENT); // Set background to transparent so we don't see the white...
int howmany = sizeof(mybuffer) * 2;
DisplayTime *= 500;
int p = 0;
while(p < DisplayTime)
{
// Shadow Offset
SetTextColor(hdc,RGB(0, 0, 0));
TextOut(hdc,x+2,y+2, (LPCWSTR)mybuffer,howmany);
// Primary text
SetTextColor(hdc,RGB(255, 0, 0));
TextOutW(hdc,x,y,(LPCWSTR)mybuffer,howmany);
UpdateWindow(hWnd);
p++;
Sleep(2);
}
ReleaseDC(hWnd,hdc);
_endthreadex(0);
}
I've looked through multiple examples, checked the syntax, and made sure that I didn't mess up on _beginthreadex, but can't seem to find the cause of the problem :|
回答1:
In a nutshell thread startup functions need to follow an exact prototype, and not the one you used.
They can accept a function that takes a single void *.
There are several solutions.
- Change your function to accept a void*. Right away cast it to a 'struct *' of some type you have created and has the data you want. You would typically create the struct in main with new/malloc, and then delete/free it when you don't need it in the thread function.
- The somewhat cleaner alternative is to 'new' up an object of a class you have made. Give that class a public static method that takes said void *. Use the static method as the thread starter, and pass the address of the object as 'this'. Then have the static cast the void * to the object type and call some 'start/run' routine on the object proper. Have the object delete itself before returning from the thread routine unless you have a more coordinated solution across the threads.
回答2:
_beginthreadex(0, 0, DrawText,(void *)(hwnd, 175, 15, text, 8), 0 , &threadID);
According to MSDN, third argument must be pointer to a function whose argument is of type void*
. In your case, DrawText
is a function whose argument is not void*
but (HWND hWnd, float x, float y, wchar_t* mybuffer, float DisplayTime)
. Hence the error and take a look at the examples in the link.
来源:https://stackoverflow.com/questions/9714041/beginthreadex-cannot-convert-from-overloaded-function