开发者

Basic Windows API

I've been trying to get a basic program going with the windows API (WinMain and WndProc) and have completed 4 tutorials now, all of which say the same thing. I create the two vital functions previously mentioned but when I compile and run no window is shown.

I get no errors or crashes, the program runs fine it's just the window that should but doesn't appear.

Any help would be great, I've tried using a Win32 Console project setup, a Win32 project setup and an Empty Project setup in VS2010.

Thanks.

EDIT: Apologies, here is the code I am using to set up and show the window:

WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASS));

wcex.cbSize = sizeof(WNDCLASS);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = 0;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = "MyWindowClass";
wcex.hIconSm = 0;

RegisterClassEx(&wcex);

HWN开发者_开发技巧D hWnd = CreateWindowEx(NULL, "MyWindowClass",       // Name of window class
                         "Window Name",         // Title of window
                         WS_OVERLAPPEDWINDOW,   // Window style
                         300, 500,              // x,y position of window
                         800, 600,              // w,h of window
                         NULL,                  // Parent window
                         NULL,                  // Menus
                         hInstance,             // Application handle
                         NULL);                 // Multiple windows

ShowWindow(hWnd, nCmdShow);


 wcex.lpfnWndProc = (WNDPROC)WndProc;

That's a very fishy cast, it should never be necessary. This problem is otherwise explained by a borked window procedure. You didn't post it. Start by deleting the cast and solve any compile error you get. Make sure that it always calls DefWindowProc() for messages you don't process yourself.

Consider using the boilerplate code you get from selecting the Win32 Project project template to get these details right.


ZeroMemory(&wcex, sizeof(WNDCLASS));

wcex.cbSize = sizeof(WNDCLASS)

The above parameters should have been WNDCLASSEX to match the WNDCLASSEX structure defined just above them.


There's a really great introduction to building your first Win32 application available on MSDN.

You won't get very far after that (the "next" link in the series starts teaching you about Windows Forms, which is humorous but irrelevant to your goal). But if your goal is just to learn what the boilerplate is, this is a great place to look.

Alternatively, as I mentioned in a comment, you should be able to create a new Win32 project in Visual Studio and get all that basic stuff inserted for you automatically. Of course, then you'll have the battle of understanding it all, but that's not what you're asking here. :-)

Here's the basic skeleton from that tutorial:

int WINAPI _tWinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(wcex);
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_3DFACE + 1);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(NULL,
            _T("Call to RegisterClassEx failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    hInst = hInstance; // Store instance handle in our global variable

    // The parameters to CreateWindow explained:
    // szWindowClass: the name of the application
    // szTitle: the text that appears in the title bar
    // WS_OVERLAPPEDWINDOW: the type of window to create
    // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    // 500, 100: initial size (width, length)
    // NULL: the parent of this window
    // NULL: this application dows not have a menu bar
    // hInstance: the first parameter from WinMain
    // NULL: not used in this application
    HWND hWnd = CreateWindow(
        szWindowClass,
        szTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 100,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
    {
        MessageBox(NULL,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Guided Tour"),
            NULL);

        return 1;
    }

    // The parameters to ShowWindow explained:
    // hWnd: the value returned from CreateWindow
    // nCmdShow: the fourth parameter from WinMain
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);    // send the window a WM_PAINT message

    // Main message loop:
    BOOL bRet;
    MSG msg;
    while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
    {
        if (bRet == -1)
        {
            MessageBox(NULL,
                _T("Error encountered in message loop!"),
                _T("Win32 Guided Tour"),
                NULL);

            return 1;
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}


You don't get errors because you've not called ::GetLastError(). Print out the value returned by GetLastError after each API call.


You have no message pump, so the window is being created and closed immediately. Add the following to below your ShowWindow call:

    int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)
{
    WNDCLASSEX wcx = {0}; 
    wcx.cbSize          = sizeof(WNDCLASSEX);
    wcx.style           = 0; 
    wcx.lpfnWndProc     = (WNDPROC)::DefWindowProc; 
    wcx.cbClsExtra      = 0; 
    wcx.cbWndExtra      = 0; 
    wcx.hInstance       = hInstance; 
    wcx.hIcon           = LoadIcon(NULL, IDI_APPLICATION); 
    wcx.hCursor         = LoadCursor(NULL, IDC_ARROW); 
    wcx.hbrBackground   = (HBRUSH)GetStockObject(WHITE_BRUSH); 
    wcx.lpszMenuName    = NULL; 
    wcx.lpszClassName   = "DemoWindow"; 

    if (!RegisterClassEx(&wcx))
    {
        return -1;
    }

    HWND hWnd = CreateWindowEx( 0,                      // extended style
                                "DemoWindow",           // Window Class Name
                                "DemoWindow",           // Window Name
                                WS_OVERLAPPEDWINDOW,    // style
                                0,                      // x-position
                                0,                      // y-position
                                800,                    // width
                                600,                    // height
                                NULL,                   // parent HWND
                                NULL,                   // menu HANDLE
                                hInstance,              // instance HANDLE
                                NULL);                  // extra data

    if (NULL == hWnd)
    {
        return -1;
    }

    ShowWindow(hWnd, SW_SHOW); 
    UpdateWindow(hWnd);

    MSG msg = {0};
    while(WM_QUIT != msg.message)
    { 
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
        else
        {
            // do something useful
        }
    } 

    UnregisterClass("DemoWindow", hInstance);
    return msg.wParam;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜