🔒 Locked
WindowProc
Advertisement
Original Post
// Message Processing Functions virtual LRESULT CALLBACK AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam); bool CApplication::Create() { // Init parent window class information ZeroMemory(&m_wcx, sizeof(m_wcx)); m_wcx.cbClsExtra = 0; m_wcx.cbSize = sizeof(WNDCLASSEX); m_wcx.cbWndExtra = 0; m_wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); m_wcx.hCursor = LoadCursor(NULL, IDC_ARROW); m_wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); m_wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION); m_wcx.hInstance = m_hInstance; m_wcx.lpfnWndProc = CApplication::WndProc; m_wcx.lpszClassName = m_lpClassName; m_wcx.lpszMenuName = NULL; m_wcx.style = CS_CLASSDC; if (!RegisterClassEx(&m_wcx)) return false; // Create parent window m_hWnd = CreateWindowEx( 0, m_lpClassName, m_lpWndName, m_dwstyle, m_nXPos, m_nYPos, m_nWidth, m_nHeight, m_hWnd, NULL, m_hInstance, NULL ); if (!m_hWnd) return false; // Show and update parent window ShowWindow(m_hWnd, SW_SHOW); UpdateWindow(m_hWnd); return true; } LRESULT CApplication::AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_KEYDOWN: if (wParam == VK_ESCAPE) PostQuitMessage(0); return 0; case WM_CLOSE: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,uMsg, wParam, lParam); } ////////////////////////////////////////////////// // WndProc ////////////////////////////////////////////////// LRESULT CALLBACK CApplication::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { CApplication *w = (CApplication *) (LONG)::GetWindowLongPtr(hWnd, GWL_USERDATA); return w->AppProc(hWnd,uMsg, wParam, lParam); } ********************************************************************** In the WndProc, when I run the program, it seems error on the first statement of the WndProc Function. Since, WndProc is the static function, but I want it can call the AppProc function, how can I do it sucess? Thx ***********************************************************************
Hi bud,
You can make wndproc a static member function of your class.
Like this:
Header
CPP
Hope that helps mate,
ace
You can make wndproc a static member function of your class.
Like this:
Header
#pragma once#include <windows.h>#include <string>#include "..\\Kernel\\process.h"#include "..\\Kernel\\kernel.h"#include "..\\Kernel\\kbase.h"struct win_window_props{ unsigned int x,y; unsigned int w,h; std::string className; std::string windowCaption; win_window_props() {}; win_window_props( unsigned int x, unsigned int y, unsigned int w, unsigned int h, std::string className, std::string windowCaption) : x(x), y(y), w(w), h(h), className(className), windowCaption(windowCaption) {};};class win_window : public KERNEL::process{public: win_window(HINSTANCE instance, const std::string& label, const win_window_props& props ); ~win_window(); void Initialise( KERNEL::kernel* pKernel ); void Frame(); void Restart(); void End(); HWND& GetWindowRef() { return window; }; static LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );private: HWND window; HINSTANCE instance; static win_window* pThis; win_window_props windowProps;};CPP
#include "win_window.h"win_window::win_window(HINSTANCE instance, const std::string& label, const win_window_props& props ):process( label ){ this->instance = instance; windowProps = props;}win_window::~win_window(){}void win_window::Initialise( KERNEL::kernel* pKernel ){ this->pKernel = pKernel; this->pThis = this; // Create the window handle etc // Register the window class WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, &windowProps.className[0], NULL }; RegisterClassEx( &wc ); // Create the application's window window = CreateWindow( &windowProps.className[0], &windowProps.windowCaption[0], WS_OVERLAPPEDWINDOW, windowProps.x, windowProps.y, windowProps.w, windowProps.h, GetDesktopWindow(), NULL, this->instance, NULL ); // Show the window ShowWindow( window, SW_SHOWDEFAULT ); UpdateWindow( window );}void win_window::Frame(){ MSG msg; ZeroMemory( &msg, sizeof(msg) ); if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); }}void win_window::Restart(){}void win_window::End(){}LRESULT WINAPI win_window::MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){ switch( msg ) { case WM_DESTROY: { pThis->pKernel->SetState( KERNEL::KSC_END ); PostQuitMessage( 0 ); return 0; } } return DefWindowProc( hWnd, msg, wParam, lParam );}// Give presence to the static memberwin_window* win_window::pThis;Hope that helps mate,
ace
It seems quick complex.
I saw some forum or sample, that can use getwindowlong function
Here is my sample:
(.cpp)
LRESULT CALLBACK CApplication::AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
PostQuitMessage(0);
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,uMsg, wParam, lParam);
}
//////////////////////////////////////////////////
// WndProc
//////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CApplication *app = (CApplication*)GetWindowLong(hWnd, GWL_USERDATA);
return app->AppProc(hWnd,uMsg, wParam, lParam);
}
(.h)
public:
void Init(HINSTANCE hInstance);
bool Create();
void Run();
// Message Processing Functions
virtual LRESULT CALLBACK AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);
// Get Method
HINSTANCE GetHInstance();
HWND GetHWnd();
protected:
// Main Data
HINSTANCE m_hInstance; // Handle to application instance
HWND m_hWnd; // Handle to parent window
WNDCLASSEX m_wcx; // Structure contains parent window class information
MSG m_msg;
char* m_lpClassName; // Class name of parent window
char* m_lpWndName; // Name of parent window
DWORD m_dwstyle; // Parent window style
int m_nXPos; // Horizontal position of parent window
int m_nYPos; // Vertical position of parent window
int m_nWidth; // Parent window width
int m_nHeight; // Parent window height
};
static LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);
*******************************************
there has the warning, why?
warning C4312: 'type cast' : conversion from 'LONG' to 'CApplication *' of greater size
*******************************************
Would you mind to answer me some questions?
Why I need to use static function for the wndclassex.lpfnwndproc?
Why I cannot use the class member directly?
I saw some forum or sample, that can use getwindowlong function
Here is my sample:
(.cpp)
LRESULT CALLBACK CApplication::AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
PostQuitMessage(0);
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,uMsg, wParam, lParam);
}
//////////////////////////////////////////////////
// WndProc
//////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CApplication *app = (CApplication*)GetWindowLong(hWnd, GWL_USERDATA);
return app->AppProc(hWnd,uMsg, wParam, lParam);
}
(.h)
public:
void Init(HINSTANCE hInstance);
bool Create();
void Run();
// Message Processing Functions
virtual LRESULT CALLBACK AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);
// Get Method
HINSTANCE GetHInstance();
HWND GetHWnd();
protected:
// Main Data
HINSTANCE m_hInstance; // Handle to application instance
HWND m_hWnd; // Handle to parent window
WNDCLASSEX m_wcx; // Structure contains parent window class information
MSG m_msg;
char* m_lpClassName; // Class name of parent window
char* m_lpWndName; // Name of parent window
DWORD m_dwstyle; // Parent window style
int m_nXPos; // Horizontal position of parent window
int m_nYPos; // Vertical position of parent window
int m_nWidth; // Parent window width
int m_nHeight; // Parent window height
};
static LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);
*******************************************
there has the warning, why?
warning C4312: 'type cast' : conversion from 'LONG' to 'CApplication *' of greater size
*******************************************
Would you mind to answer me some questions?
Why I need to use static function for the wndclassex.lpfnwndproc?
Why I cannot use the class member directly?
(.h)
(*.cpp)
*********************************************
1. What is the usage of WIndowLongPtr?
2. The Error is on run-time:
"Unhandled exception at 0x0042307b in 3DPRGApp.exe: 0xC000000005: Access violation reading location 0X00000000.
And the error is point to "return app->App(hwnd, uMsg, wParam, lParam);
***********************************************
I am really sorry make all of you trouble becuase my english is not really good, may be I don't fully understand the MSDN.. Hope you can help me ...and many many thanks.
#ifndef CORE_APPLICATION_H#define CORE_APPLICATION_Hclass CApplication{public: CApplication(); // Constructor virtual ~CApplication(); // Destructorpublic: void Init(HINSTANCE hInstance); bool Create(); void Run(); virtual bool Render(); // Message Processing Functions virtual LRESULT CALLBACK AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam); // Get Method HINSTANCE GetHInstance(); HWND GetHWnd();protected: // Main Data HINSTANCE m_hInstance; // Handle to application instance HWND m_hWnd; // Handle to parent window WNDCLASSEX m_wcx; // Structure contains parent window class information MSG m_msg; char* m_lpClassName; // Class name of parent window char* m_lpWndName; // Name of parent window DWORD m_dwStyle; // Parent window style int m_nXPos; // Horizontal position of parent window int m_nYPos; // Vertical position of parent window int m_nWidth; // Parent window width int m_nHeight; // Parent window height};static LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);#endif(*.cpp)
[sourcelang="cpp"]//////////////////////////////////////////////////// Include//////////////////////////////////////////////////#include "CApplication.h"//////////////////////////////////////////////////// Constructor//////////////////////////////////////////////////CApplication::CApplication(){ m_hInstance = NULL; m_hWnd = NULL; m_lpClassName = "CoreAppWnd"; m_lpWndName = "Core Game"; m_dwStyle = WS_OVERLAPPEDWINDOW; m_nXPos = 0; m_nYPos = 0; m_nWidth = 800; m_nHeight = 600;}//////////////////////////////////////////////////// Destructor//////////////////////////////////////////////////CApplication::~CApplication(){}//////////////////////////////////////////////////// Init//////////////////////////////////////////////////void CApplication::Init(HINSTANCE hInstance){ m_hInstance = hInstance;}//////////////////////////////////////////////////// Create//////////////////////////////////////////////////bool CApplication::Create(){ // Init parent window class information ZeroMemory(&m_wcx, sizeof(m_wcx)); m_wcx.cbClsExtra = 0; m_wcx.cbSize = sizeof(WNDCLASSEX); m_wcx.cbWndExtra = 0; m_wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); m_wcx.hCursor = LoadCursor(NULL, IDC_ARROW); m_wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); m_wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION); m_wcx.hInstance = m_hInstance; m_wcx.lpfnWndProc = WndProc; m_wcx.lpszClassName = m_lpClassName; m_wcx.lpszMenuName = NULL; m_wcx.style = CS_CLASSDC; if (!RegisterClassEx(&m_wcx)) return false; // Create parent window m_hWnd = CreateWindowEx( 0, m_lpClassName, m_lpWndName, m_dwStyle, m_nXPos, m_nYPos, m_nWidth, m_nHeight, m_hWnd, NULL, m_hInstance, NULL ); if (!m_hWnd) return false; // Show and update parent window ShowWindow(m_hWnd, SW_SHOW); UpdateWindow(m_hWnd); return true;}//////////////////////////////////////////////////// Run//////////////////////////////////////////////////void CApplication::Run(){ ZeroMemory(&m_msg, sizeof(MSG)); while (m_msg.message != WM_QUIT) { if (PeekMessage(&m_msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&m_msg); DispatchMessage(&m_msg); } else { if (!Render()) break; } } UnregisterClass(m_lpClassName, m_hInstance);}//////////////////////////////////////////////////// Render//////////////////////////////////////////////////bool CApplication::Render(){ return true;}//////////////////////////////////////////////////// AppProc//////////////////////////////////////////////////LRESULT CALLBACK CApplication::AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg) { case WM_KEYDOWN: if (wParam == VK_ESCAPE) PostQuitMessage(0); return 0; case WM_CLOSE: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,uMsg, wParam, lParam);}//////////////////////////////////////////////////// WndProc//////////////////////////////////////////////////LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam){ CApplication *app = (CApplication *) (LONG_PTR)::GetWindowLongPtr(hWnd, GWLP_USERDATA); return app->AppProc(hWnd,uMsg, wParam, lParam);/* switch (uMsg) { case WM_KEYDOWN: if (wParam == VK_ESCAPE) PostQuitMessage(0); return 0; case WM_CLOSE: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,uMsg, wParam, lParam);*/}//////////////////////////////////////////////////// GetHInstance//////////////////////////////////////////////////HINSTANCE CApplication::GetHInstance(){ return m_hInstance;}//////////////////////////////////////////////////// GetHWnd//////////////////////////////////////////////////HWND CApplication::GetHWnd(){ return m_hWnd;}*********************************************
1. What is the usage of WIndowLongPtr?
2. The Error is on run-time:
"Unhandled exception at 0x0042307b in 3DPRGApp.exe: 0xC000000005: Access violation reading location 0X00000000.
And the error is point to "return app->App(hwnd, uMsg, wParam, lParam);
***********************************************
I am really sorry make all of you trouble becuase my english is not really good, may be I don't fully understand the MSDN.. Hope you can help me ...and many many thanks.
This article here on Gamedev, and this one at Code Project are useful for learning how to do this. The second one is written for Windows CE, but there are notes for applying it to desktop versions of Windows.
Hey,
I had this problem too. I received an exception the whole time and I just coudn't find a solution for it...
After looking good at my source I discovered that I didn't passed 'this' as last parameter for CreateWindowEx.
I hope this post was helpfull.
Goodluck,
Walter
I had this problem too. I received an exception the whole time and I just coudn't find a solution for it...
After looking good at my source I discovered that I didn't passed 'this' as last parameter for CreateWindowEx.
I hope this post was helpfull.
Goodluck,
Walter
Quote:I just ran a quick test and WM_GETMINMAXINFO appears to be the first message, followed by WM_NCCREATE.
Original post by Anonymous Poster
I have heard that WM_NCCREATE is not the actual first message from other places, though, so you will have to debug if this is not the case.
Here's a neat hack I've used once or twice which (except for being extremely unportable) works great. It's fast, catches all messages and won't collide with anything when subclassing foreign widgets.
Basically it works by building a new function dynamically for each object and embedding the instance pointer directly into the code.
template <typename ClassT, typename StaticT, typename MemberT>class Functor { unsigned char _code[10];public: void Bind(ClassT *instance, MemberT target) { union { MemberT proc; const unsigned char *raw; } converter = { target }; _code[0] = 0xb9; // mov ecx,instance (const void * &) _code[1] = instance; _code[5] = 0xe9; // jmp target (unsigned &) _code[6] = converter.raw - &_code[10]; } operator StaticT() { return (StaticT) &_code; }};// wrap up a few WinAPI callbackstemplate <typename T>class WndProcFunctor : public Functor<T, WNDPROC, HRESULT (T::*)(HWND, UINT, WPARAM, LPARAM)> { };template <typename T>class DlgProcFunctor : public Functor<T, DLGPROC, BOOL (T::*)(HWND, UINT, WPARAM, LPARAM)> { };template <typename T>class HookProcFunctor : public Functor<T, HOOKPROC, LRESULT (T::*)(int, WPARAM, LPARAM)> { };
(.h)class CApplication{public: CApplication(); // Constructor virtual ~CApplication(); // Destructorpublic: void Init(HINSTANCE hInstance); bool Create(); void Run(); virtual bool Render(); // Message Processing Functions virtual LRESULT CALLBACK AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam); // Get Method HINSTANCE GetHInstance(); HWND GetHWnd();protected: // Main Data HINSTANCE m_hInstance; // Handle to application instance HWND m_hWnd; // Handle to parent window WNDCLASSEX m_wcx; // Structure contains parent window class information MSG m_msg; char* m_lpClassName; // Class name of parent window char* m_lpWndName; // Name of parent window DWORD m_dwStyle; // Parent window style int m_nXPos; // Horizontal position of parent window int m_nYPos; // Vertical position of parent window int m_nWidth; // Parent window width int m_nHeight; // Parent window height};static LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam);(.cpp)LRESULT CALLBACK CApplication::AppProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam){ switch (uMsg) { case WM_KEYDOWN: if (wParam == VK_ESCAPE) PostQuitMessage(0); return 0; case WM_CLOSE: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,uMsg, wParam, lParam);}//////////////////////////////////////////////////// WndProc//////////////////////////////////////////////////LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam){ CApplication *app = (CApplication *) (LONG_PTR)::GetWindowLongPtr(hWnd, GWLP_USERDATA); return app->AppProc(hWnd,uMsg, wParam, lParam); }Would you mind to tell me why I try to handle the WM_NCCREATE still not work
Would you mind to modify my program and tell me why your change can be workable
I am really very thanks your help >_<
This is what you have to do in your static WndProc:
-- Begin shameless plug
Btw, I have designed a much easier way to write Windows applications (which uses this technique under the hood). This makes it all too easy (easier than any other approach I've seen) to write a Windows app.
Basically you can write a Windows app like this:
And then if you decide you need a HDC for drawing in your on_mousemove-function, you just add it and everything works! You don't have to change anything but the on_mousemove-function! And of course it works with member-functions in a class as well!
Anyone who's interested can read about the thinking behind it at http://amag.rotd.org/tutorials.php
I hope I will be able to finish the next part of the tutorial where I describe how to apply the technique described for Windows programming.
I also hope I will be able to clean up the source code enough so I can release it!
-- End shameless plug
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam){ CApplication *app = 0; if(uMsg == WM_NCCREATE) { const LPCREATESTRUCT cs = reinterpret_cast<const LPCREATESTRUCT>(lParam); app = reinterpret_cast<CApplication *>(cs.lpCreateParams); ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(app)); } else { app = (CApplication *) (LONG_PTR)::GetWindowLongPtr(hWnd, GWLP_USERDATA); } if(app) return app->AppProc(hWnd,uMsg, wParam, lParam); else return DefWindowProc(hWnd, uMsg, wParam, lParam); }-- Begin shameless plug
Btw, I have designed a much easier way to write Windows applications (which uses this technique under the hood). This makes it all too easy (easier than any other approach I've seen) to write a Windows app.
Basically you can write a Windows app like this:
void on_paint(HDC hdc) { ... }void on_mousemove(POINTS p) { ... }and WinMain:int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR cmd_line, int cmd_show){ init_winlib(instance); window w = create_window("Hello World"); w.message(WM_PAINT) += &on_paint; w.message(WM_MOUSEMOVE) += &on_mousemove; w.show_window(cmd_show); main_loop();}And then if you decide you need a HDC for drawing in your on_mousemove-function, you just add it and everything works! You don't have to change anything but the on_mousemove-function! And of course it works with member-functions in a class as well!
Anyone who's interested can read about the thinking behind it at http://amag.rotd.org/tutorials.php
I hope I will be able to finish the next part of the tutorial where I describe how to apply the technique described for Windows programming.
I also hope I will be able to clean up the source code enough so I can release it!
-- End shameless plug
The following MUST work, i'm using it too:
Window.h
Window.cpp
[Edited by - WalterTamboer on November 23, 2005 4:52:04 AM]
Window.h
#ifndef WINDOW_H#define WINDOW_Hclass Window{public: Window( /* your stuff in here */ ) { } ~Window() { }private: static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam); public: void create(); void destroy(); inline HWND getHWND() { return hWnd; } inline void setHWND(HWND hwnd) { this->hWnd = hwnd; } private: HWND hWnd; HINSTANCE hInstance;};#endifWindow.cpp
#include "Window.h"LRESULT CALLBACK Window::StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ // Example: http://blogs.msdn.com/oldnewthing/archive/2005/04/22/410773.aspx // Example: http://www.gamedev.net/reference/articles/article1810.asp Window *wnd = 0; if (uMsg == WM_NCCREATE) { LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); wnd = reinterpret_cast<Window *>(lpcs->lpCreateParams); wnd->setHWND(hwnd); SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(wnd)); } else { wnd = reinterpret_cast<Window *> (GetWindowLongPtr(hwnd, GWLP_USERDATA)); } if (wnd) return wnd->WndProc(uMsg, wParam, lParam); return DefWindowProc(hwnd, uMsg, wParam, lParam);}LRESULT Window::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam){ // Do your thing... return DefWindowProc(hwnd, uMsg, wParam, lParam);}void Window::create(){ // Create the window... hWnd = CreateWindowEx( WS_EX_APPWINDOW | WS_EX_TOPMOST, // extended style "CLASS", // class "TITLE", // title WS_POPUP, // style 0, 0, // position x and y 640, // width 480, // height 0, // handle to parent 0, // handle to menu hInstance, // instance of the application this // This will be passed when the message loop is created );}void Window::destroy(){ // Destroy your window}};[Edited by - WalterTamboer on November 23, 2005 4:52:04 AM]
CApplication *app = 0; if(uMsg == WM_NCCREATE) { const LPCREATESTRUCT cs = reinterpret_cast<const LPCREATESTRUCT>(lParam); app = reinterpret_cast<CApplication *>(cs.lpCreateParams); ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(app)); } else { app = (CApplication *) (LONG_PTR)::GetWindowLongPtr(hWnd, GWLP_USERDATA); } if(app) return app->AppProc(hWnd,uMsg, wParam, lParam); else return DefWindowProc(hWnd, uMsg, wParam, lParam);but there has error:
Error C2228: left of 'lpCreateParams' must have class/struct/union type
warning C4244: 'argument': conversion from 'LONG_PTR' to 'LONG', possible loss of data
WHY?
CApplication *wnd = 0; if (uMsg == WM_NCCREATE) { LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam); wnd = reinterpret_cast<CApplication *>(lpcs->lpCreateParams); wnd->setHWND(hWnd); SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LPARAM>(wnd)); } else { wnd = reinterpret_cast<CApplication *> (GetWindowLongPtr(hWnd, GWLP_USERDATA)); } if (wnd) return wnd->AppProc(hWnd, uMsg, wParam, lParam); return DefWindowProc(hWnd, uMsg, wParam, lParam);If I used this approach, than I will have this problme:
warning C4244: 'argument': conversion from 'LPARAM' to 'LONG', possible loss of data
warning C4312: 'reinterpet_case' conversion from 'LONG' to 'CApplication *' of greater size
error LNK2001: unresolved external symbol "public : virutal long_stdcall CGameApp::AppProc(struct HWND_ *, unsigned int, unsigned int, long)" (?AppProc@CGameApp@@UAGJPAUHWND_@@IIJ@Z)
fatal error LNK1120: 1unresolved externals
WHY >_<
Quote:
but there has error:
Error C2228: left of 'lpCreateParams' must have class/struct/union type
warning C4244: 'argument': conversion from 'LONG_PTR' to 'LONG', possible loss of data
Uhm, since I just wrote that code without letting it through any compiler I missed that it should say:
app = reinterpret_cast<CApplication *>(cs->lpCreateParams);The warning you get is, uhm, a compiler bug, it annoys me too but there's nothing to do except turning off 64-bit compatibility warnings.
For a 32-bit program LONG and LONG_PTR will be of the same size (32 bits), but in a 64-bit program LONG_PTR will be 64 bits.
The problem is that for a 32-bit program SetWindowLongPtr() is simply a macro around SetWindowLong(), so if you pass a LONG_PTR to SetWindowLongPtr() it will actually go to SetWindowLong() which only accepts a LONG, now as I said for a 32-bit app, sizeof(LONG) == sizeof(LONG_PTR), so it's no problem, except that the compiler has been told to look for conversions from LONG_PTR to LONG and warn about it...
The linker error means that there's no body for the member function AppProc() in the class CGameApp. If there is make sure the signatures of the declaration and definition of AppProc() are exactly the same!
Having said that you need to investigate any of the other possible errors yourself a bit before you post a response, you can't just post what the compiler spits out and expect us to fix/debug/write the whole program for you...
Good luck!
Right click on *Your Project*
-> properties
-> C/C++
-> General
-> Detect 64 bit Portability Issues
-> Choose No
[EDIT]
Google can be your friend ;)
Second hit:
http://www.google.nl/search?q=how+to+turn+off+64-bit+compatibility+warnings
-> properties
-> C/C++
-> General
-> Detect 64 bit Portability Issues
-> Choose No
[EDIT]
Google can be your friend ;)
Second hit:
http://www.google.nl/search?q=how+to+turn+off+64-bit+compatibility+warnings
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement