views:

45

answers:

4

I have this class here that I made based on another one I had. It is supposed to handle the whole creating windows and stuff, but it seems to be getting into a hang now. The older version used to work fine, I don't know WHAT I may have forgotten to add to this one that might be causing it to hang like this.

This is the message loop:

int Window::HandleMessages()
{
    while(GetMessage(&this->windat.msgs, NULL, 0, 0))
    {
        TranslateMessage(&this->windat.msgs);
        DispatchMessage(&this->windat.msgs);
    }
    return this->windat.msgs.wParam;
}

Pretty basic stuff, I don't know why, but it will simply hang... When I run the program, it'll just show me an empty prompt window, and by testing, I got it to show a message box if I used it before the while loop, but inside it doesn't work. I've been trying to compare both this class and the older one and haven't figured out what might be wrong with this. Could anyone tell me what could possibly trigger this behaviour? Thanks

A: 

Use PeekMessage instead of GetMessage.

Andrei K.
OK, so I tried it like that... by messing around with the MessageBox again, it seems like the program never receives any messages, as the alert box will keep on appearing when in the while loop, but when I put it inside the if(PeekMessage... it will simply not appear :/
A: 

OK, now this left me pretty confused. By messing around with GetLastError, it seems that it is returning error 2 (file not found) ANYWHERE I put it, even if right at the start of the Main, before I instantiate my Window class. If I call GetLastError anytime after CreateWindowEx, it'll return an error like 1047 or something, about class not found or something. HWND becomes NULL too
Here is the code for the main.cpp:

#include "SimpWin/SimpWin.h"
#include <stdio.h>

//  Make the class name into a global variable
char szClassName[] = "WindowsApp";


void ErrorExit(LPTSTR lpszFunction)
{
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError();

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
    sprintf((char*)lpDisplayBuf,
        TEXT("%s failed with error %d: %s"),
        lpszFunction, dw, lpMsgBuf);
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw);
}

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    ErrorExit(TEXT("CreateWindowEx"));
    Window* win = Window::CreateWindowClass(hThisInstance, szClassName, WindowProcedure);
    if(!win->Register())
    {
        return 0;
    }


    win->Show(nFunsterStil);

    int res = win->HandleMessages();

    delete win;

    return res;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProc (hwnd, message, wParam, lParam);
}

This here, is the code for the Window::Register function:

int Window::Register()
{
    if(this->windat.wincl.hIcon == NULL)
    {
        this->windat.wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    }
    if(this->windat.wincl.hIconSm == NULL)
    {
        this->windat.wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    }

    if(!RegisterClassEx(&this->windat.wincl))
    {
        return 0;
    }



    this->windat.hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           (char*) this->windat.sName,                  /* Classname */
           (char*) this->windat.sTitle,       /* Title Text */
           WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           this->windat.cDimension.width,         /* The programs width */
           this->windat.cDimension.height,        /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           this->windat.hInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    return 1;
}

I'm lost here, I don't know why the eff this is going on... :/

A: 

Check the return value to GetMessage() - your while loop won't exit if there are errors. It should look like this:

while (GetMessage(&this->windat.msgs, NULL, 0, 0) > 0)
{
 ...
}
JBRWilkinson
Regardless of what the type signature suggests, `GetMessage` does not return a boolean value.
Ben Voigt
Why the downvote? Check the doc link, quote 'return value can be nonzero, zero, or -1'
JBRWilkinson
A: 

Well, I finally got it working! :D

It actually had to do with a completely unrelated class I had here. It is a String class (which descended from Array) which I made, and the copy function had a bug, it would copy the character array I passed to it, but would not update the length field of the class... That copy function would be called whenever I had to set the class to a value through operator=. The length is required for the operator char* to convert the class to c-format string. I'd use that cast when passing the ClassName and Title values to CreateWindowEx, and it would return me an array of 0 chars, and that's where hell happened.
Now I fixed that lib up, and it's working fine now. Thanks :D