2016-05-06 8 views
0

ここでいくつかのWinAPIを学び、WNDPROCをwcex.lpfnWndProcに渡して問題に遭遇しようとしましたが、それはすべて正常ですが、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'引数の二番目の引数とは何かを持っていることがありますが、 'のchar [7を渡します] '。 'wchar_t className [] = Lで試してください。" Winnie "' –

+1

あなたのキャストはすべて偽です。それらを削除し、エラーを修正してください。あなたはドキュメントを読む必要があります。また、エラーのチェックを開始する必要があります。戻り値は無視しないでください。 –

+0

学習のために、これらのクラスを使用するのではなく、プレーンなWinAPIから始めることをお勧めします。 Charles PetzoldのWindows Programming 5th Editionは良いスタートですが、1998年からのものです。当時の唯一の大きな変化はUnicodeで、 'char'の代わりに' wchar_t'を使用しました –

答えて

3

問題はあなたのウィンドウの手順ではありません。それはclassNameである。あなたのコンストラクタは、LPCWSTR、a.k.a、wchar_t const*となるように定義されています。しかし、classNamecharの配列であり、wchar_tの配列ではありません。しかし、あなたは私が現時点ではしませんが、あなたのコードで他の問題の無数を持って

wchar_t className[] = L"Winnie"; 

:あなたはとしてそれを宣言することでこのエラーを修正することができます。

+1

これらの行に沿って、 'WNDCLASSEX'の代わりに' WNDCLASSEXW'を使用し、 'CreateWindowEx()'の代わりに 'CreateWindowExW()'を呼び出す必要があります。また、['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:しかし、私はあなたが 'TCHAR'とは対照的に' wchar_t'を明示的に使うつもりならば、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; 
} 
関連する問題