好吧,這是一個非常奇怪的問題。我想先說我不是C++的初學者,我當然不會進步。我在中間的某個地方。我想要做的是製作Win32 API的C++ OOP包裝庫(dll)。這是我的圖書館的類。調用虛擬函數時崩潰
g++ -shared -o bin\win32oop.dll src\Application.cpp src\Form\Form.cpp -Wall
的src \ Application.h:
#ifndef WOOP_APPLICATION_H_
#define WOOP_APPLICATION_H_
namespace Woop
{
class Application
{
public:
bool Init(void);
virtual bool OnInit(void);
};
}
#endif // WOOP_APPLICATION_H_
的src \ Application.cpp
#include <windows.h>
#include "Application.h"
#include "Form\Form.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
namespace Woop
{
bool Application::Init(void)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "woop";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(RegisterClassEx(&wc) == 0)
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return false;
}
this->OnInit();
return true;
}
bool Application::OnInit(void)
{
return true;
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Woop::Form *wnd = 0;
if (uMsg == WM_NCCREATE)
{
SetWindowLong (hwnd, GWL_USERDATA, long((LPCREATESTRUCT(lParam))->lpCreateParams));
}
wnd = (Woop::Form *)(GetWindowLong (hwnd, GWL_USERDATA));
if (wnd) return wnd->WndProc(hwnd, uMsg, wParam, lParam);
return ::DefWindowProc (hwnd, uMsg, wParam, lParam);
}
的src \表格\ Form.h
我使用下面的命令編譯的MinGW它#ifndef WOOP_FORM_FORM_H_
#define WOOP_FORM_FORM_H_
namespace Woop
{
class Form
{
public:
bool Show(void);
virtual LRESULT WndProc(HWND, UINT, WPARAM, LPARAM);
protected:
HWND _handle;
};
}
#endif // WOOP_FORM_FORM_H_
src \ Form \ Form.cpp
#include <windows.h>
#include "Form.h"
namespace Woop
{
bool Form::Show(void)
{
_handle = CreateWindowEx(WS_EX_CLIENTEDGE, "woop", "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, GetModuleHandle(NULL), this);
if(_handle == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return false;
}
ShowWindow(_handle, SW_SHOWNORMAL);
return true;
}
LRESULT Form::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
這裏是一個我正在與測試庫的程序:
class SampleApp : public Woop::Application
{
bool OnInit(void)
{
Form form;
form.Show();
return true;
}
};
INT APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
{
SampleApp application;
if(application.Init() == false) return 0;
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0;
}
好了,現在的問題。你看到Form類中的虛擬窗口過程嗎?如果我從聲明中刪除虛擬,程序編譯並運行良好。但是當我加回來時,它會崩潰。臭名昭着的「不發送」對話框出現了。我不知道它什麼時候崩潰,我會嘗試使用MessageBox()來弄清楚()(lol,這是我沒有學習如何使用gdb進行調試的結果)。我試圖讓我可以創建一個類,比如LoginForm,並從窗體派生並覆蓋窗口過程。我希望我能夠很好地解釋這個問題:D。這可能是一個編譯器錯誤或我的愚蠢:P。無論如何,在此先感謝。
是從'GetWindowLong()'並且轉換爲'Form *'(在全局的'WndProc()')中實際上是一個指向Form的有效指針?如果不是,那麼虛擬呼叫會爆炸。 – 2010-07-30 18:26:30
看看你在這裏做什麼,我會說看看這本書:http://www.amazon.com/MFC-Internals-Microsoft-Foundation-Architecture/dp/0201407213/(MFC內部,由喬治牧羊人)它恕我直言很好*解釋通過什麼箍MS微軟跳轉到獲得他們的MFC C++ OO API運行在Win32窗口系統之上。 – 2010-07-30 18:30:43
感謝您的參考martin。我正在尋找一本關於在C++ OOP中封裝Win32的好書。 – 2010-07-30 18:40:24