2010-10-02 2 views
1

У меня есть этот класс здесь, который я сделал на основе другого, который у меня был. Предполагается, что он обрабатывает все создаваемые окна и прочее, но, похоже, теперь он становится висеть. Раньше версия работала нормально, я не знаю, ЧТО Я, возможно, забыл добавить к этому, что может вызвать зависание.C++ - Окно цикла сообщений замораживается

Это цикл обработки сообщений:

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

Довольно основной материал, я не знаю, почему, но это будет просто повесить ... Когда я запускаю программу, она будет просто показать мне пустую и после тестирования я получил его, чтобы показать окно сообщения, если я использовал его до цикла while, но внутри он не работает. Я пытаюсь сравнить и этот класс, и старый, и не понял, что может быть неправильно с этим. Может ли кто-нибудь сказать мне, что может вызвать это поведение? Благодаря


ОК, теперь это оставило меня очень смущен. Погрузившись с GetLastError, кажется, что он возвращает ошибку 2 (файл не найден) В любом случае я помещаю его, даже если это правильно в начале Main, прежде чем я создам экземпляр класса Window. Если я вызову GetLastError в любое время после CreateWindowEx, он вернет ошибку, например 1047 или что-то вроде класса, не найденного или чего-то еще. HWND становится NULL слишком
Вот код 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); 
} 

Это здесь, это код для окна :: Регистрация функции:

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; 
} 

Я потерял здесь, Я не знаю, почему это происходит ...:/

+0

Похоже, что это пропуск вообще. –

ответ

0

Используйте PeekMessage вместо GetMessage.

+0

ОК, поэтому я попробовал это так ... снова возился с MessageBox, кажется, что программа никогда не получает никаких сообщений, так как окно предупреждения будет появляться, когда в цикле while, но когда я помещаю его внутрь if (PeekMessage ... он просто не появится:/ – user464503

0

Проверьте return value to GetMessage() - ваш цикл while не будет выходить, если есть ошибки. Это должно выглядеть так:

while (GetMessage(&this->windat.msgs, NULL, 0, 0) > 0) 
{ 
... 
} 
+0

Независимо от того, что предлагает подпись типа, 'GetMessage' не возвращает логическое значение. –

+0

Почему downvote? Проверьте ссылку doc, quote 'return value может быть отличным от нуля , ноль или -1 ' – JBRWilkinson

0

Ну, наконец, я получил его! : D

На самом деле это было связано с совершенно несвязанным классом, который у меня был здесь. Это класс String (который произошел из Array), который я создал, и функция копирования имела ошибку, она скопировала бы массив символов, который я передал ему, но не обновил бы поле длины класса ... Эта копия функция будет вызываться всякий раз, когда мне приходилось устанавливать класс в значение через operator =. Длина требуется для оператора char * для преобразования класса в строку c-format. Я использовал бы это при передаче значений ClassName и Title в CreateWindowEx, и он вернет мне массив из 0 символов, и вот что случилось.
Теперь я исправил это lib, и теперь он работает нормально. Спасибо: D

+0

Привет, но почему ошибка класса заставила вас думать, что она висит в GetMessage? Я имею в виду, вы считали, что она остановлена ​​в GetMessage, а не в другом месте кода, правильно? – ransh

0

Несмотря на то, что это довольно старый ... от MSDN on GetMessage:

В отличие от GetMessage, функция PeekMessage не ждать, пока сообщение будет размещен перед возвращением.

То есть, GetMessage ждет следующего сообщения, которое станет доступен. Вы рассматриваете это ожидание как замораживание, предположительно, потому что у вас на самом деле не было намерения ждать сообщений.

Обратите внимание, что вы можете прикрепить отладчик во время предполагаемого замораживания, приостановить выполнение и проверить стеки вызовов потоков. Как только вы найдете свой поток и стек вызовов, а его GetMessage будет выполняться в стеке, вы достаточно хорошо изолируете проблему, чтобы знать, где читать документальное поведение.

Смежные вопросы