2016-05-06 5 views
0

пытается узнать о WinAPI здесь и столкнуться с проблемой передачи WNDPROC в мой wcex.lpfnWndProc, все в порядке с объявлением, но я получаю сообщение об ошибке при вызове MyWinClass (WNDPROC, LPCWSTR, HINSTANCE);WNDCLASSEX не принимает параметр WNDPROC

Ошибка в функции WinMain в нижней части этого раздела кода.

Источник Я учусь от датирована 1998, но это было самое интуитивное (для меня Personaly), она была замена старых версий, таких как WNDCLASS с расширенными версиями WNDCLASSEX, CreateWindowEx и т.д ...

#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

это может иметь что-то делать со вторым аргументом 'MyWinClass' аргумент объявлен как' LPCWSTR' и вы передавая 'полукокса [7 ] '. Попробуйте его с помощью 'wchar_t className [] = L" Winnie "' –

+1

Ваши броски все фиктивные. Удалите их и исправьте свои ошибки. Вам нужно будет прочитать документы. Вы также захотите начать проверку на наличие ошибок. Не игнорируйте возвращаемые значения. –

+0

Для обучения я рекомендую вам начать с простого WinAPI вместо использования этих классов. Чарльз Петцольд в Windows Programming 5th Edition - хорошее начало, это также с 1998 года. Единственное серьезное изменение с тех дней - Unicode, вместо этого используйте 'wchar_t'' char' –

ответ

3

Проблема не в вашей процедуре окна. Это с className. Ваш конструктор определяется как LPCWSTR, a.k.a, wchar_t const*. Но className представляет собой массив char, а не массив 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; 
} 
Смежные вопросы