2016-05-06 19 views
0

試圖在這裏學習一些WinAPI,並且遇到了麻煩,將WNDPROC傳遞給了我的wcex.lpfnWndProc,它在decleration中一切正常,但當我調用MyWinClass(WNDPROC,LPCWSTR,HINSTANCE)時出現錯誤;WNDCLASSEX沒有使用WNDPROC參數

錯誤出現在此代碼部分底部的WinMain函數中。

我從學源是於1998年,但它一直是最直觀的(對於我本人來說),它已與擴展版本WNDCLASSEX,CreateWindowEx等更換舊的版本,如WNDCLASS ...

#include <Windows.h> 
#include <string> 
using namespace std; 

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 

class MyWinClass 
{ 
public: 
    MyWinClass(WNDPROC winProc, LPCWSTR className, HINSTANCE hInst); 
    void Register() 
    { 
     ::RegisterClassEx(&wcex); 
    } 
private: 
    WNDCLASSEX wcex; 
}; 

MyWinClass::MyWinClass(WNDPROC winProc, LPCWSTR className, HINSTANCE hInst) 
{ 
    wcex.style = 0; 
    wcex.lpfnWndProc = winProc; 
    wcex.cbClsExtra = 0; 
    wcex.cbWndExtra = 0; 
    wcex.hInstance = hInst; 
    wcex.hIcon = 0; 
    wcex.hCursor = LoadCursor(0, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
    wcex.lpszMenuName = 0; 
    wcex.lpszClassName = className; 
} 

class CreateMyWindow 
{ 
public: 
    CreateMyWindow() : _hwnd(0){} 
    CreateMyWindow(char const * caption, char const * className, HINSTANCE hInstance); 
    void ShowWindow(int cmdShow) 
    { 
     ::ShowWindow(_hwnd, cmdShow); 
     ::UpdateWindow(_hwnd); 
    } 
protected: 
    HWND _hwnd; 
}; 

CreateMyWindow::CreateMyWindow(char const * caption, char const * className, HINSTANCE hInstance) 
{ 
    _hwnd = ::CreateWindowEx(
     (DWORD)className, 
     (LPCWSTR)caption, 
     WS_OVERLAPPED, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     0, 
     0, 
     NULL, 
     hInstance, 
     0); 
} 


//MyWindow Procedure that is called by windows 

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
     case WM_DESTROY: 
      PostQuitMessage(0); 
      return 0; 
    } 
    return DefWindowProc(hwnd, message, wParam, lParam); 
} 


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow) 
{ 
    char className[] = "Winnie"; 

    MyWinClass myWinClass(WindowProcedure, className, hInst); 
    /*Error: no Instance of constructor "MYWinClass::MYWinClass" mat the argument list argument types are:(LRESULT _stdcall(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) char[7], HINSTANCE) 

//MyWinClass myWinClass(WindowProcedure...) us underlined with above error, and I do not know why it is seeing WNDPROC as an HWND.*/ 
    myWinClass.Register(); 

    CreateMyWindow myWndClass("MyWindowClass", className, hInst); 
    myWndClass.ShowWindow(cmdShow); 

    MSG msg; 

    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    return msg.wParam; 
} 
+0

這可能是與聲明爲'LPCWSTR'了'MyWinClass'爭論的第二個參數,你傳遞'炭[7 ]'。試試'wchar_t className [] = L「Winnie」' –

+1

你的演員都是假的。刪除它們並修復錯誤。您需要閱讀文檔。您還需要開始檢查錯誤。不要忽略返回值。 –

+0

對於學習,我建議您從簡單的WinAPI開始,而不是使用這些類。 Charles Petzold的Windows Programming 5th Edition是一個很好的開始,它也是從1998年開始的。從那時起,唯一的重大變化是Unicode,使用'wchar_t'而不是'char' –

回答

3

這個問題不是你的窗口過程。它與className。您的構造函數被定義爲採取LPCWSTR,a.k.a,wchar_t const*。但是classNamechar的數組,而不是數組wchar_t。您可以通過聲明爲解決此錯誤

wchar_t className[] = L"Winnie"; 

但是,您有其他問題,您的代碼,我不會進入,此時萬千。

+1

沿着這些路線,您需要使用'WNDCLASSEXW'而不是'WNDCLASSEX',並且調用'CreateWindowExW()'而不是'CreateWindowEx()'。並閱讀['CreateWindowEx()'文檔](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632680.aspx),你甚至沒有傳遞正確的參數。 –

+0

@RemyLebeau:這取決於是否定義了「UNICODE」。如果是,則WNDCLASSEX爲WNDCLASSEXW,CreateWindowEx爲CreateWindowExW。如果不是,那麼WNDCLASSEX是WNDCLASSEXA,CreateWindowEx是CreateWindowExA。 –

+0

@RemyLebeau:但是我同意,如果你要明確使用'wchar_t'(而不是'TCHAR'),你應該明確你想在WinAPI中使用寬字符版本的類和函數。 –

2

您正在以不正確的方式混合ANSI和Unicode數據,並且您的某些類型轉換是錯誤的。嘗試一些更喜歡這個:

#include <Windows.h> 

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 

class MyWinClass 
{ 
public: 
    MyWinClass(WNDPROC winProc, LPCTSTR className, HINSTANCE hInst); 

    void Register() 
    { 
     ::RegisterClassEx(&wcex); 
    } 

private: 
    WNDCLASSEX wcex; 
}; 

MyWinClass::MyWinClass(WNDPROC winProc, LPCTSTR className, HINSTANCE hInst) 
{ 
    wcex.style = 0; 
    wcex.lpfnWndProc = winProc; 
    wcex.cbClsExtra = 0; 
    wcex.cbWndExtra = 0; 
    wcex.hInstance = hInst; 
    wcex.hIcon = 0; 
    wcex.hCursor = LoadCursor(0, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
    wcex.lpszMenuName = 0; 
    wcex.lpszClassName = className; 
} 

class CreateMyWindow 
{ 
public: 
    CreateMyWindow() : _hwnd(0){} 
    CreateMyWindow(LPCTSTR caption, LPCTSTR className, HINSTANCE hInstance); 

    void ShowWindow(int cmdShow) 
    { 
     ::ShowWindow(_hwnd, cmdShow); 
     ::UpdateWindow(_hwnd); 
    } 

protected: 
    HWND _hwnd; 
}; 

CreateMyWindow::CreateMyWindow(LPCTSTR caption, LPCTSTR className, HINSTANCE hInstance) 
{ 
    _hwnd = ::CreateWindowEx(
     0, 
     className, 
     caption, 
     WS_OVERLAPPED, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     NULL, 
     NULL, 
     hInstance, 
     NULL); 
} 


//MyWindow Procedure that is called by windows 

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
     case WM_DESTROY: 
      PostQuitMessage(0); 
      return 0; 
    } 

    return DefWindowProc(hwnd, message, wParam, lParam); 
} 


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow) 
{ 
    TCHAR className[] = TEXT("Winnie"); 

    MyWinClass myWinClass(WindowProcedure, className, hInst); 
    myWinClass.Register(); 

    CreateMyWindow myWndClass(TEXT("MyWindowClass"), className, hInst); 
    myWndClass.ShowWindow(cmdShow); 

    MSG msg; 

    while (::GetMessage(&msg, NULL, 0, 0)) 
    { 
     ::TranslateMessage(&msg); 
     ::DispatchMessage(&msg); 
    } 

    return msg.wParam; 
} 

或者:

#include <Windows.h> 

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 

class MyWinClass 
{ 
public: 
    MyWinClass(WNDPROC winProc, LPCWSTR className, HINSTANCE hInst); 

    void Register() 
    { 
     ::RegisterClassExW(&wcex); 
    } 

private: 
    WNDCLASSEXW wcex; 
}; 

MyWinClass::MyWinClass(WNDPROC winProc, LPCWSTR className, HINSTANCE hInst) 
{ 
    wcex.style = 0; 
    wcex.lpfnWndProc = winProc; 
    wcex.cbClsExtra = 0; 
    wcex.cbWndExtra = 0; 
    wcex.hInstance = hInst; 
    wcex.hIcon = 0; 
    wcex.hCursor = LoadCursor(0, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
    wcex.lpszMenuName = 0; 
    wcex.lpszClassName = className; 
} 

class CreateMyWindow 
{ 
public: 
    CreateMyWindow() : _hwnd(0){} 
    CreateMyWindow(LPCWSTR caption, LPCWSTR className, HINSTANCE hInstance); 

    void ShowWindow(int cmdShow) 
    { 
     ::ShowWindow(_hwnd, cmdShow); 
     ::UpdateWindow(_hwnd); 
    } 

protected: 
    HWND _hwnd; 
}; 

CreateMyWindow::CreateMyWindow(LPCWSTR caption, LPCWSTR className, HINSTANCE hInstance) 
{ 
    _hwnd = ::CreateWindowExW(
     0, 
     className, 
     caption, 
     WS_OVERLAPPED, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     NULL, 
     NULL, 
     hInstance, 
     NULL); 
} 


//MyWindow Procedure that is called by windows 

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
     case WM_DESTROY: 
      PostQuitMessage(0); 
      return 0; 
    } 

    return DefWindowProc(hwnd, message, wParam, lParam); 
} 


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow) 
{ 
    WCHAR className[] = L"Winnie"; 

    MyWinClass myWinClass(WindowProcedure, className, hInst); 
    myWinClass.Register(); 

    CreateMyWindow myWndClass(L"MyWindowClass", className, hInst); 
    myWndClass.ShowWindow(cmdShow); 

    MSG msg; 

    while (::GetMessage(&msg, NULL, 0, 0)) 
    { 
     ::TranslateMessage(&msg); 
     ::DispatchMessage(&msg); 
    } 

    return msg.wParam; 
} 
相關問題