[英]Windows C++ - Creating window in a class makes it look unusual
好的,所以我做了一個創建HWND的類。
但是,創建的窗口顯示了一些奇怪的屬性:它與其他窗口不同-它是不透明的,close-minimize-maximize按鈕的位置與普通窗口不同。
但是指定的樣式是默認樣式(WM_OVERLAPPEDWINDOW)。
而且,除非我稍稍移動一下,否則它就無法關閉(好像它在移動前未生成WM_DESTROY或WM_CLOSE消息)。
這可能與WinProc主程序使用指針調用另一個消息處理程序的實現有關。 但是,我不知道為什么窗戶看起來異常。
我的代碼:
//mywind.h
class Window
{
private:
HWND mHwnd;
const char* className="Window";
static LRESULT CALLBACK StartWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); //main WindowProc function
LRESULT ThisWindowProc(UINT msg, WPARAM wParam, LPARAM lParam); //Another, object-specific message processing function
bool isClassRegistered(HINSTANCE hinst);
public:
Window() : mHwnd( 0 ) { }
~Window();
int create(std::string title, int width, int height);
};
//mywind.cpp
Window::~Window()
{
if( mHwnd ) DestroyWindow( mHwnd );
}
int Window::create(std::string title, int width, int height)
{
WNDCLASS wincl;
HINSTANCE hInst = NULL;
hInst = GetModuleHandle(NULL);
if(hInst==NULL)
{
printf("Failed to load hInstance\n");
return -1;
}
if(!GetClassInfo(hInst, className, &wincl))
{
printf("Getting class info.\n");
wincl.style = 0;
wincl.hInstance = hInst;
wincl.lpszClassName = className;
wincl.lpfnWndProc = StartWindowProc;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hIcon = NULL;
wincl.hCursor = NULL;
wincl.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wincl.lpszMenuName = NULL;
if(!isClassRegistered(hInst))
{
if (RegisterClass(&wincl) == 0)
{
printf("The class failed to register.\n");
return 0;
}
}
}
mHwnd = CreateWindow(className, title.c_str(), WS_VISIBLE | WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
NULL, NULL, hInst, this);
if(mHwnd==NULL)
{
printf("Failed to create HWND.\n");
return -1;
}
MSG msg;
while(GetMessage(&msg, mHwnd, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
printf("Destroying window.\n");
if(mHwnd) DestroyWindow(mHwnd);
mHwnd=NULL;
printf("Returning.\n");
return msg.wParam;
}
bool Window::isClassRegistered(HINSTANCE hinst)
{
WNDCLASSEX clinf;
if(!GetClassInfoEx(hinst, className, &clinf)) return false;
return true;
}
LRESULT CALLBACK Window::StartWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Window* winp = NULL;
if(msg == WM_CREATE)
{
CREATESTRUCT* cs = (CREATESTRUCT*) lParam;
winp = (Window*) cs->lpCreateParams;
SetLastError(0);
if(SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) winp) == 0)
{
if(GetLastError()!=0) return -1;
}
}
else
{
winp = (Window*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
if(winp) return winp->ThisWindowProc(msg, wParam, lParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT Window::ThisWindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_PAINT:
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(mHwnd, msg, wParam, lParam);
}
return 0;
}
//main.cpp
#include "mywind.h"
int main(int argc, char* argv[])
{
Window mwnd;
mwnd.create("Test", 200, 200);
return 0;
}
請注意,直到CreateWindowEx
返回時才設置mHwnd
。 這意味着在窗口創建期間發送的所有消息都將0
傳遞給DefWindowProc
而不是實際的窗口句柄。 這使窗口管理器認為您正在繞過默認處理並執行自定義標題,這就是為什么一切看起來不正確的原因。
TL; DR:在WM_NCCREATE
處理程序中設置mHwnd
。
我90%確信您的問題是缺少清單,該清單使WinXP / 7看起來更漂亮。 現在您處於兼容模式,並且窗口框架適用於Windows 98/2000樣式。 有關更多詳細信息,請閱讀此鏈接(或針對同一問題的許多其他鏈接): http : //www.mctainsh.com/Articles/Csharp/XpControlsInCS.aspx
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.