This question already has answers here:
How to declare an __stdcall function pointer
(1 answer)
Function pointer and calling convention
(3 answers)
Closed 8 months ago.
does anybody know if is possible to add __stdcall (CALLBACK) in function parameter like this?:
void Function(LRESULT CALLBACK (*f)(HWND, UINT, WPARAM, LPARAM));
It gives me following error:
a calling convention may not be followed by a nested declarator
Any solutions?
Thx in advance <3
Put the calling convention inside the parenthesis.
void Function(LRESULT (CALLBACK *f)(HWND, UINT, WPARAM, LPARAM));
Usually it is seen in the manual, for example CallWindowProcW function
the lpPrevWndFunc parameter has the data type WNDPROC. The WNDPROC type is declared as follows:
LRESULT (CALLBACK* WNDPROC) (HWND, UINT, WPARAM, LPARAM);
Thus, the correct syntax is (WNDPROC -> f)
void Function(LRESULT (CALLBACK* f)(HWND, UINT, WPARAM, LPARAM));
Related
So I am in the process of creating a WNDCLASSEX within a method contained in D3DApp class which I am going to be deriving from with another class e.g. Engine, Game, etc... called InitMainWindow (which is also protected in the base class):
bool D3DApp::InitMainWindow() {
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc; // This is where the error is!
wc.hInstance = mAppInst;
wc.hCursor = LoadCursor(mAppInst, IDC_ARROW);
wc.lpszClassName = L"MainWindow";
RegisterClassEx(&wc);
RECT rect = { 0,0,SCREEN_WIDTH,SCREEN_HEIGHT };
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
mMainWnd = CreateWindowEx(NULL, L"MainWindow", L"Test", WS_OVERLAPPEDWINDOW, 300, 300, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, mAppInst, NULL);
ShowWindow(mMainWnd, NULL);
return true;
}
My WNDPROC Callback declaration and definition is within the same D3DApp base class where InitMainWindow() is located, defined as such:
virtual LRESULT WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
When I am filling out the lpfnWndProc variable within the WNDCLASSEX struct I receive a C2440 error stating the following
'=': cannot convert from 'LRESULT (__cdecl D3DApp::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'
Do I have to create a definition of my WNDPROC Callback in the class deriving from D3DApp? Or do I have to completely remove this callback from the base class and derived class and place it outside and above the scope of my WinMain function? I've been researching for about 2 days on how to fix this error and have had no luck on finding any possible fixes... I think my C++ skills just may not be as excellent as I think they are. But if anyone can help me understand where my problem is that would be amazing!
p.s and yes I know I have some error checking to do but I just want to make sure it works for my compiler first :)
Here's the signature of WNDPROC:
typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
but your declaration is different:
LRESULT WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
You should either declare it outside of the class like this:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
or declare it as static and remove virtual keyword. Also notice, you should add CALLBACK which resolves to __stdcall calling convention as your project is configured to use __cdecl calling convention
I created this account to ask a question because I'm pretty lost right now and I couldn't find an answer. I'm not sure if what I'm trying to do is even possible, or perhaps I'm taking an incorrect approach.
I'm writing a windows socket wrapper class for asynchronous sockets, mostly so I never have to write this code again, and I'm trying to store a function pointer as a member variable inside my netcode class that points to a windows event handler that's called inside the application's normal win32 message pump that points elsewhere. Basically, I'm trying to create a programmer-defined callback function so that when I compile this netcode class into a .dll I never have to touch it again.
As a clarification, what I'm trying to do is, for example, write the event handler for WM_SOCKET (which is a windows message I have defined) somewhere other than inside the network code class (so it can be portable to different win32/C++ projects) and outside of the main win32 message pump (so my WndProc() doesn't become absolutely massive).
I don't even know what to search for, but all of the information I'm finding is about creating a pointer to a member function or a member of a template, which isn't what I want.
Here's the code I've already tried to write (only the relevant bits), which is what is giving me problems. I'm probably royally screwing something up here.
//// Sockets.h
class NetworkConnection
{
private:
void (*WMSocketFunction)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
public:
void HandleEvents(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void registerSocketFunction( void (*SocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)));
};
//// Sockets.cpp
#include "Sockets.h"
void NetworkConnection::registerSocketFunction( void (*SocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)))
{
WMSocketFunction = SocketFunction;
};
void NetworkConnection::HandleEvents(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WMSocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
}
//// Application.cpp
void SocketEventHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Do socket stuff here
};
int SetupApp()
{
NetworkConnection NetConnection;
NetConnection.registerSocketFunction(&SocketEventHandler);
return 0;
}
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_SOCKET:
{
NetConnection.HandleEvents(hwnd, msg, wParam, lParam);
break;
}
case WM_DESTROY:
{
ReleaseDevices();
break;
}
case WM_KEYDOWN:
{
#ifdef _DEBUG
if (lParam == VK_ESCAPE)
PostQuitMessage(0);
#endif
}
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
I'd be really grateful for some help, here. I totally have no clue why this isn't working.
The errors I receive are:
Error 1 error C2440: '=' : cannot convert from 'void *(__cdecl *)(HWND,UINT,WPARAM,LPARAM)' to 'void (__cdecl *)(HWND,UINT,WPARAM,LPARAM)' sockets.cpp (in function registerSocketFunction)
Error 2 error C2275: 'HWND' : illegal use of this type as an expression sockets.cpp (in function HandleEvents)
Error 3 error C2146: syntax error : missing ')' before identifier 'hwnd' sockets.cpp (in function HandleEvents)
Error 4 error C2059: syntax error : ')' sockets.cpp (in function HandleEvents)
Error 8 error C2664: 'NetworkConnection::registerSocketFunction' : cannot convert parameter 1 from 'void (__cdecl *)(HWND,UINT,WPARAM,LPARAM)' to 'void *(__cdecl *)(HWND,UINT,WPARAM,LPARAM)' application.cpp
If you need any better explanation, because I've likely explained this problem poorly, please don't hesitate to ask.
I'm using Visual Studio 2010, so I don't think I can use C++/11 features like std::function.
Exclude arguments names from function pointer declaration
Use typedef to make code cleaner
typedef void(*WMSocketFunction_Ptr)(HWND, UINT, WPARAM, LPARAM);
class NetworkConnection
{
private:
WMSocketFunction_Ptr WMSocketFunction;
public:
void HandleEvents(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void registerSocketFunction(WMSocketFunction_Ptr SocketFunction);
};
void NetworkConnection::registerSocketFunction(WMSocketFunction_Ptr SocketFunction)
{
WMSocketFunction = SocketFunction;
};
Prefer to use STL facilities to naked pointers: std::function of boost::function
typedef std::function<void(HWND, UINT, WPARAM, LPARAM)> WMSocketFunction_Ptr;
You have to enclose the function pointer name in brackets like this: void (*SocketFunction)(...)
So instead of your method declaration:
void registerSocketFunction( void (*SocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)));
You have to write:
void registerSocketFunction( void (*SocketFunction)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam));
Also rewrite your method body to this:
void NetworkConnection::registerSocketFunction( void (*SocketFunction)(HWND, UINT, WPARAM, LPARAM))
{
WMSocketFunction = SocketFunction;
};
Next thing, i think your HandleEvents is unfinished yet, you have a syntax error there, i think you wanted to call the function behind the pointer.
void NetworkConnection::HandleEvents(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
WMSocketFunction(hwnd,msg,wParam,lParam);
}
Here is my suspicion. I think the way you've declared the function argument SocketFunction for registerSocketFunction is wrong.
void NetworkConnection::registerSocketFunction( void (*SocketFunction(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)))
should be,
void NetworkConnection::registerSocketFunction( void (*SocketFunction)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam))
I ran a similar test on GCC, and it threw a similar error, so this might be your problem.
I began C++ quite recently and I obviously have the famous LNK2019 issue. I roamed a few hours on google but nothing solved my problem.
My project is half way coded, since I separate the view and the model.
I work with Visual Studio 2010.
Here is the class whose function is not retrieved:
Display.h:
#ifndef DEF_DISPLAY
#define DEF_DISPLAY
#include <Windows.h>
#include <exception>
class Display{
public:
HWND mainWindow, gameWindow;
WNDCLASS mainClass, gameClass;
public:
Display();
static LRESULT CALLBACK mainWindowProc(HWND mainWin, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK gameWindowProc(HWND gameWin, UINT message, WPARAM wParam, LPARAM lParam);
**int run();** // This function is not retrieved by the linker.
};
#endif
And here is the Display.cpp:
#include "Display.h"
HINSTANCE instanceMain = 0, instanceGame = 0;
Display::Display(){...}
LRESULT CALLBACK Display::mainWindowProc(HWND mainWin, UINT message, WPARAM wParam, LPARAM lParam){...}
LRESULT CALLBACK Display::gameWindowProc(HWND gameWin, UINT message, WPARAM wParam, LPARAM lParam){...}
int run(){
MSG message;
while(GetMessage(&message, 0, 0, 0)){
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}
And finally here is my main.cpp:
#include "Display.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow){
Display game;
return game.run();
}
I did not finished to code my project because I found out that issue when building it:
1> All outputs are up-to-date.
1>main.obj : error LNK2019: unresolved external symbol "public: int __thiscall Display::run(void)" (?run#Display##QAEHXZ) referenced in function _WinMain#16
1>C:\Users\glembalis\Documents\Visual Studio 2010\Projects\pendu\Debug\pendu.exe : fatal error LNK1120: 1 unresolved externals
1>
1>Build FAILED.
I don't know where the error can occur.
Display.h and Display.cpp are included in the project
The option in Project > Properties > Linker > System > SubSystem is "Windows"
I do not use external libraries (only Windows.h and exception)
The compiler seems to work well. I don't really care if the program works properly, I would correct it later. For now, this linker issue is my major concern! I guess it is just a tiny little stupid mistake, but I cannot find it out!
Thanks to everyone for your time and attention, looking forward to have your answers! Last, I apologise but english is not my native language and I may have written some mistakes.
Have a nice day!
NoobFeeder
Your definition (implementation) has the wrong signature.
It should look like this:
int Display::run(){
This tells the compiler that your run is the one that's a member of your Display class.
Currently you have implemented a free function called run.
I'm sure it is something real easy I've overlooked but I'm tearing my hair over this error message. I very seldom use friend functions.
error: 'LRESULT Window_Proc(HWND, UINT, WPARAM, LPARAM)' should have been declared inside '::'
Here's my definition:
namespace rayc
{
class win32_window: public window {
public:
win32_window();
~win32_window();
void show();
void hide();
void pump_message();
private:
friend LRESULT CALLBACK ::Window_Proc(HWND, UINT, WPARAM, LPARAM);
void set_closed(bool);
HWND hWin;
};
}
I don't quite understand this error message, it is defined as belonging to global scope, is it not?!
Compiling with MinGW-64 TDM.
I don't quite understand this error message, it is defined as belonging to global scope, is it not?!
It is not, unless you have included a forward declaration at the global namespace before that friend declaration. If a friend declaration introduces a new symbol, then such symbol is located at the enclosing namespace of the class that contains it.
Try adding
LRESULT CALLBACK Window_Proc(HWND, UINT, WPARAM, LPARAM);
at the global namespace, before declaring your class.
I'm trying to write this win32 program with WinApi and I'm stuck because the tutorial I'm following seems to have a problem.
MainWindow.h:
class MainWindow
{
public:
MainWindow(HINSTANCE);
~MainWindow(void);
LRESULT CALLBACK WndProcedure(HWND, UINT, WPARAM, LPARAM);
// [...]
MainWindow.cpp:
MainWindow::MainWindow(HINSTANCE hInstance) : hwnd(0)
{
WNDCLASSEX WndClsEx;
// [...]
WndClsEx.lpfnWndProc = &MainWindow::WndProcedure;
// [...]
}
LRESULT CALLBACK MainWindow::WndProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
// [...]
}
I must be referencing MainWindow::WndProcedure wrong because I'm following the signature exactly as the tutorial says, however the lpfnWndProc line in the constructor gives a compile-time error:
error C2440: '=' : cannot convert from 'LRESULT (__stdcall MainWindow::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'
replace
LRESULT CALLBACK WndProcedure(HWND, UINT, WPARAM, LPARAM);
by
static LRESULT CALLBACK WndProcedure(HWND, UINT, WPARAM, LPARAM);
The this pointer is a hidden parameter in your function call and by declaring it static the this pointer is not a parameter anymore and the signature of the two functions match.
That's because your WndProcedure function must be either a global function or a static member function.
You can't use a non-static member function as a window procedure. If you declare WndProcedure as static it should compile. A non-member function would work as well.
Non-static member functions have a different signature than static members. This is because they receive an implicit this parameter in addition to the explicitly defined parameters.