ShowWindow неверный дескриптор окна

Недавно я пытался создать класс окна, используя Windows API в C ++. Однако всякий раз, когда я пытаюсь вызвать ShowWindow, функция устанавливает последнюю ошибку в 1400 (ERROR_INVALID_WINDOW_HANDLE). Попробовав некоторое время, я наткнулся на следующий пример:
http://blogs.msdn.com/b/oldnewthing/archive/2005/04/22/410773.aspx#comments

Даже создав новый проект (я использую MSVC Express 2008) и точно скопировав код (что мне не хочется делать), я обнаружил, что, хотя код успешно создал окно, функция ShowWindow по-прежнему сообщает об ошибке 1400. Вот выдержка из код найден по ссылке выше:

int PASCAL
WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int nShowCmd)
{
g_hinst = hinst;

if (SUCCEEDED(CoInitialize(NULL))) {
InitCommonControls();

RootWindow *prw = RootWindow::Create();
if (prw) {
ShowWindow(prw->GetHWND(), nShowCmd);
int error = GetLastError(); //Line added by me, error gets set to 1400.
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CoUninitialize();
}
return 0;
}

(Полный код можно найти по ссылке выше)

Если у кого-то есть идеи о том, как использовать дескриптор окна в качестве переменной-члена класса без получения ошибки 1400 в ShowWindow, я был бы очень признателен за помощь.

3

Решение

   ShowWindow(prw->GetHWND(), nShowCmd);
int error = GetLastError();

Это не правильный код. Единственный раз, когда допустимо вызывать GetLastError (), это когда функция winapi не удалось. Если вы используете GetLastError (), когда они не в противном случае вы получите совершенно случайное число. ShowWindow () немного отличается тем, что вообще не генерирует код ошибки, поэтому использование GetLastError () никогда правильный.

Общий шаблон примерно:

if (!SomeWinapiFunction(...)) {
int error = GetLastError();
CrashAndBurn(error);
}

Но проверьте документацию MSDN, чтобы увидеть, какое возвращаемое значение указывает на ошибку и подходит ли GetLastError (). Например, это не относится к функциям GDI. Обязательно исправьте это и в других частях вашего кода. Правильная обработка ошибок очень важно, когда вы используете сырой API. В частности, обратите внимание, что ваш метод RootWindow :: Create () не имеет хорошего способа указать на неудачу при создании окна. Это должно быть исправлено. Исключения, конечно, очень хороший способ сделать это.

6

Другие решения

У меня такая же проблема. Решение было двигаться DefWindowProc () от дефолт до конца WndProc ().

До:

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
static HBITMAP hBitMap;
static int cxSizeBitMap;
static int cySizeBitMap;
static int cxClient;
static int cyClient;
HDC hdc;
BITMAP bitMap;
PAINTSTRUCT ps;
HDC hMem;
HINSTANCE      hInstance ;
switch( message )
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
hBitMap = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BRICK ) );
GetObject( hBitMap, sizeof(BITMAP), &bitMap );
cxSizeBitMap = bitMap.bmWidth;
cySizeBitMap = bitMap.bmHeight;
break;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
break;
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
hMem = CreateCompatibleDC( hdc );
SelectObject( hMem,  hBitMap );
for (int y = 0 ; y < cyClient ; y += cySizeBitMap)
for (int x = 0 ; x < cxClient ; x += cxSizeBitMap)
{
BitBlt (hdc, x, y, cxSizeBitMap, cySizeBitMap, hMem, 0, 0, SRCCOPY) ;
}
DeleteDC( hMem );
EndPaint( hWnd, &ps );
break;
case WM_DESTROY:
DeleteObject( hBitMap );
PostQuitMessage( 0 );
break;
default:
// In this cast ShowWindow() will return 1400.
DefWindowProc(hWnd, message, wParam, lParam);
}

return 0;
}

После:

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
static HBITMAP hBitMap;
static int cxSizeBitMap;
static int cySizeBitMap;
static int cxClient;
static int cyClient;
HDC hdc;
BITMAP bitMap;
PAINTSTRUCT ps;
HDC hMem;
HINSTANCE      hInstance ;
switch( message )
{
case WM_CREATE:
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
hBitMap = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BRICK ) );
GetObject( hBitMap, sizeof(BITMAP), &bitMap );
cxSizeBitMap = bitMap.bmWidth;
cySizeBitMap = bitMap.bmHeight;
break;
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
break;

case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
hMem = CreateCompatibleDC( hdc );

// Было SelectObject( hdc,  hMem );
SelectObject( hMem,  hBitMap );
// Было BitBlt( hdc, 0, 0, cxSize, cySize, hMem, 0, 0, DIB_RGB_COLORS);
for (int y = 0 ; y < cyClient ; y += cySizeBitMap)
for (int x = 0 ; x < cxClient ; x += cxSizeBitMap)
{
BitBlt (hdc, x, y, cxSizeBitMap, cySizeBitMap, hMem, 0, 0, SRCCOPY) ;
}DeleteDC( hMem );
EndPaint( hWnd, &ps );
break;
case WM_DESTROY:
DeleteObject( hBitMap );
PostQuitMessage( 0 );
break;
}

// In this case ShowWindow() will show the window.
return DefWindowProc(hWnd, message, wParam, lParam);;
}
0

По вопросам рекламы [email protected]