/**************************************************************************** * * File: testdd.cpp * Project: DxDiag (DirectX Diagnostic Tool) * Author: Mike Anderson (manders@microsoft.com) * Purpose: Test DirectDraw functionality on this machine * * (C) Copyright 1998 Microsoft Corp. All rights reserved. * ****************************************************************************/ #include #define DIRECTDRAW_VERSION 5 // run on DX5 and later versions #include #include "reginfo.h" #include "sysinfo.h" #include "dispinfo.h" #include "testdd.h" #include "resource.h" #ifndef ReleasePpo #define ReleasePpo(ppo) \ if (*(ppo) != NULL) \ { \ (*(ppo))->Release(); \ *(ppo) = NULL; \ } \ else (VOID)0 #endif enum TESTID { TESTID_LOAD_DDRAW_DLL= 1, TESTID_GET_DIRECTDRAWCREATE, TESTID_DIRECTDRAWCREATE, TESTID_GETCAPS, TESTID_USER_VERIFY_RECTANGLES, TESTID_USER_VERIFY_WINDOW_BOUNCE, TESTID_USER_VERIFY_FULLSCREEN_BOUNCE, TESTID_SETCOOPERATIVELEVEL_NORMAL, TESTID_CREATEPRIMARYSURFACE, TESTID_GETPRIMARYSURFACEDESC, TESTID_COLORFILL_BLT_TO_PRIMARY, TESTID_CREATE_OFFSCREENPLAIN_SURFACE, TESTID_COLORFILL_BLT_TO_OFFSCREENPLAIN, TESTID_BLT_OFFSCREENPLAIN_TO_FRONT, TESTID_CREATE_TEST_WINDOW, TESTID_SETCOOPERATIVELEVEL_FULLSCREEN, TESTID_SETDISPLAYMODE, TESTID_CREATEPRIMARYSURFACE_FLIP_ONEBACK, TESTID_GETATTACHEDSURFACE, TESTID_COLORFILL_TO_BACKBUFFER, TESTID_FLIP, }; typedef HRESULT (WINAPI* LPDIRECTDRAWCREATE)(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter); BOOL BTranslateError(HRESULT hr, TCHAR* psz, BOOL bEnglish = FALSE); // from main.cpp (yuck) static HRESULT TestPrimary(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed); static HRESULT TestPrimaryBlt(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed); static HRESULT TestFullscreen(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed); static HRESULT CreateTestWindow(HWND hwndMain, HWND* phwnd); /**************************************************************************** * * TestDD * ****************************************************************************/ VOID TestDD(HWND hwndMain, DisplayInfo* pDisplayInfo) { HRESULT hr = S_OK; TCHAR szPath[MAX_PATH]; HINSTANCE hInstDDraw = NULL; LPDIRECTDRAWCREATE pDDCreate; LPDIRECTDRAW pdd = NULL; TCHAR sz[300]; TCHAR szTitle[100]; LoadString(NULL, IDS_STARTDDTEST, sz, 300); LoadString(NULL, IDS_APPFULLNAME, szTitle, 100); if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO)) return; // Remove info from any previous test: ZeroMemory(&pDisplayInfo->m_testResultDD, sizeof(TestResult)); pDisplayInfo->m_testResultDD.m_bStarted = TRUE; // Load ddraw.dll GetSystemDirectory(szPath, MAX_PATH); lstrcat(szPath, TEXT("\\ddraw.dll")); hInstDDraw = LoadLibrary(szPath); if (hInstDDraw == NULL) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_LOAD_DDRAW_DLL; pDisplayInfo->m_testResultDD.m_hr = DDERR_NOTFOUND; goto LEnd; } // Get DirectDrawCreate entry point pDDCreate = (LPDIRECTDRAWCREATE)GetProcAddress(hInstDDraw, "DirectDrawCreate"); if (pDDCreate == NULL) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_GET_DIRECTDRAWCREATE; pDisplayInfo->m_testResultDD.m_hr = DDERR_NOTFOUND; goto LEnd; } // Call DirectDrawCreate if (FAILED(hr = pDDCreate(&pDisplayInfo->m_guid, &pdd, NULL))) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_DIRECTDRAWCREATE; pDisplayInfo->m_testResultDD.m_hr = hr; goto LEnd; } // Get DirectDraw caps DDCAPS ddcaps; DDCAPS ddcaps2; ddcaps.dwSize = sizeof(ddcaps); ddcaps2.dwSize = sizeof(ddcaps2); if (FAILED(hr = pdd->GetCaps(&ddcaps, &ddcaps2))) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_GETCAPS; pDisplayInfo->m_testResultDD.m_hr = hr; goto LEnd; } ReleasePpo(&pdd); if (!pDisplayInfo->m_bCanRenderWindow) { LoadString(NULL, IDS_SKIPWINDOWED, sz, 300); MessageBox(hwndMain, sz, szTitle, MB_OK); } else { // First test LoadString(NULL, IDS_DDTEST1, sz, 300); if (IDCANCEL == MessageBox(hwndMain, sz, szTitle, MB_OKCANCEL)) { pDisplayInfo->m_testResultDD.m_bCancelled = TRUE; goto LEnd; } if (FAILED(hr = pDDCreate(&pDisplayInfo->m_guid, &pdd, NULL))) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_DIRECTDRAWCREATE; pDisplayInfo->m_testResultDD.m_hr = hr; goto LEnd; } if (FAILED(hr = TestPrimary(hwndMain, pdd, &pDisplayInfo->m_testResultDD.m_iStepThatFailed))) { pDisplayInfo->m_testResultDD.m_hr = hr; goto LEnd; } ReleasePpo(&pdd); LoadString(NULL, IDS_CONFIRMDDTEST1, sz, 300); if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO)) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_USER_VERIFY_RECTANGLES; pDisplayInfo->m_testResultDD.m_hr = S_OK; goto LEnd; } // Second test LoadString(NULL, IDS_DDTEST2, sz, 300); if (IDCANCEL == MessageBox(hwndMain, sz, szTitle, MB_OKCANCEL)) { pDisplayInfo->m_testResultDD.m_bCancelled = TRUE; goto LEnd; } if (FAILED(hr = pDDCreate(&pDisplayInfo->m_guid, &pdd, NULL))) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_DIRECTDRAWCREATE; pDisplayInfo->m_testResultDD.m_hr = hr; goto LEnd; } if (FAILED(hr = TestPrimaryBlt(hwndMain, pdd, &pDisplayInfo->m_testResultDD.m_iStepThatFailed))) { pDisplayInfo->m_testResultDD.m_hr = hr; goto LEnd; } ReleasePpo(&pdd); LoadString(NULL, IDS_CONFIRMDDTEST2, sz, 300); if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO)) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_USER_VERIFY_WINDOW_BOUNCE; pDisplayInfo->m_testResultDD.m_hr = S_OK; } } // Third test LoadString(NULL, IDS_DDTEST3, sz, 300); if (IDCANCEL == MessageBox(hwndMain, sz, szTitle, MB_OKCANCEL)) { pDisplayInfo->m_testResultDD.m_bCancelled = TRUE; goto LEnd; } if (FAILED(hr = pDDCreate(&pDisplayInfo->m_guid, &pdd, NULL))) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_DIRECTDRAWCREATE; pDisplayInfo->m_testResultDD.m_hr = hr; goto LEnd; } POINT ptMouse; GetCursorPos(&ptMouse); if (FAILED(hr = TestFullscreen(hwndMain, pdd, &pDisplayInfo->m_testResultDD.m_iStepThatFailed))) { pDisplayInfo->m_testResultDD.m_hr = hr; goto LEnd; } SetCursorPos( ptMouse.x, ptMouse.y ); ReleasePpo(&pdd); LoadString(NULL, IDS_CONFIRMDDTEST3, sz, 300); if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO)) { pDisplayInfo->m_testResultDD.m_iStepThatFailed = TESTID_USER_VERIFY_FULLSCREEN_BOUNCE; pDisplayInfo->m_testResultDD.m_hr = S_OK; goto LEnd; } LoadString(NULL, IDS_ENDDDTESTS, sz, 300); MessageBox(hwndMain, sz, szTitle, MB_OK); LEnd: ReleasePpo(&pdd); if (hInstDDraw != NULL) FreeLibrary(hInstDDraw); if (pDisplayInfo->m_testResultDD.m_bCancelled) { LoadString(NULL, IDS_TESTSCANCELLED, sz, 300); lstrcpy(pDisplayInfo->m_testResultDD.m_szDescription, sz); LoadString(NULL, IDS_TESTSCANCELLED_ENGLISH, sz, 300); lstrcpy(pDisplayInfo->m_testResultDD.m_szDescription, sz); } else { if (pDisplayInfo->m_testResultDD.m_iStepThatFailed == 0) { LoadString(NULL, IDS_TESTSSUCCESSFUL, sz, 300); lstrcpy(pDisplayInfo->m_testResultDD.m_szDescription, sz); LoadString(NULL, IDS_TESTSSUCCESSFUL_ENGLISH, sz, 300); lstrcpy(pDisplayInfo->m_testResultDD.m_szDescriptionEnglish, sz); } else { TCHAR szDesc[200]; TCHAR szError[200]; if (0 == LoadString(NULL, IDS_FIRSTDDTESTERROR + pDisplayInfo->m_testResultDD.m_iStepThatFailed - 1, szDesc, 200)) { LoadString(NULL, IDS_UNKNOWNERROR, sz, 300); lstrcpy(szDesc, sz); } LoadString(NULL, IDS_FAILUREFMT, sz, 300); BTranslateError(pDisplayInfo->m_testResultDD.m_hr, szError); wsprintf(pDisplayInfo->m_testResultDD.m_szDescription, sz, pDisplayInfo->m_testResultDD.m_iStepThatFailed, szDesc, pDisplayInfo->m_testResultDD.m_hr, szError); // Nonlocalized version: if (0 == LoadString(NULL, IDS_FIRSTDDTESTERROR_ENGLISH + pDisplayInfo->m_testResultDD.m_iStepThatFailed - 1, szDesc, 200)) { LoadString(NULL, IDS_UNKNOWNERROR_ENGLISH, sz, 300); lstrcpy(szDesc, sz); } LoadString(NULL, IDS_FAILUREFMT_ENGLISH, sz, 300); BTranslateError(pDisplayInfo->m_testResultDD.m_hr, szError, TRUE); wsprintf(pDisplayInfo->m_testResultDD.m_szDescriptionEnglish, sz, pDisplayInfo->m_testResultDD.m_iStepThatFailed, szDesc, pDisplayInfo->m_testResultDD.m_hr, szError); } } } /**************************************************************************** * * TestPrimary * ****************************************************************************/ HRESULT TestPrimary(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed) { HRESULT hr = S_OK; DDSURFACEDESC ddsd; LPDIRECTDRAWSURFACE pdds = NULL; RECT rc; if (FAILED(hr = pdd->SetCooperativeLevel(NULL, DDSCL_NORMAL))) { *piStepThatFailed = TESTID_SETCOOPERATIVELEVEL_NORMAL; goto LEnd; } ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (FAILED(hr = pdd->CreateSurface(&ddsd, &pdds, NULL))) { *piStepThatFailed = TESTID_CREATEPRIMARYSURFACE; goto LEnd; } ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; if (FAILED(hr = pdds->GetSurfaceDesc(&ddsd))) { *piStepThatFailed = TESTID_GETPRIMARYSURFACEDESC; goto LEnd; } SetRect(&rc, 0, 0, ddsd.dwWidth, ddsd.dwHeight); InflateRect(&rc, -64, -64); DDBLTFX ddbltfx; ZeroMemory(&ddbltfx, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); while (rc.right > rc.left + 2 && rc.bottom > rc.top + 2) { ddbltfx.dwFillColor = ~ddbltfx.dwFillColor; if (FAILED(hr = pdds->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx))) { *piStepThatFailed = TESTID_COLORFILL_BLT_TO_PRIMARY; goto LEnd; } InflateRect(&rc, -4, -4); } // Give the user a moment to verify the test pattern Sleep(2000); // Clean up affected screen area in case this display isn't part of the desktop: ddbltfx.dwFillColor = 0; if (FAILED(hr = pdds->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx))) { *piStepThatFailed = TESTID_COLORFILL_BLT_TO_PRIMARY; goto LEnd; } LEnd: ReleasePpo(&pdds); InvalidateRect(NULL, NULL, FALSE); // repaint desktop return hr; } /**************************************************************************** * * TestPrimaryBlt * ****************************************************************************/ HRESULT TestPrimaryBlt(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed) { HRESULT hr = S_OK; DDSURFACEDESC ddsd; LPDIRECTDRAWSURFACE pddsFront = NULL; LPDIRECTDRAWSURFACE pddsBack = NULL; RECT rc; RECT rcDest; RECT rcScreen; DDBLTFX ddbltfx; INT i; LONG xv = 1; LONG yv = 2; if (FAILED(hr = pdd->SetCooperativeLevel(NULL, DDSCL_NORMAL))) { *piStepThatFailed = TESTID_SETCOOPERATIVELEVEL_NORMAL; goto LEnd; } ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (FAILED(hr = pdd->CreateSurface(&ddsd, &pddsFront, NULL))) { *piStepThatFailed = TESTID_CREATEPRIMARYSURFACE; goto LEnd; } ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; if (FAILED(hr = pddsFront->GetSurfaceDesc(&ddsd))) { *piStepThatFailed = TESTID_GETPRIMARYSURFACEDESC; goto LEnd; } SetRect(&rcScreen, 0, 0, ddsd.dwWidth, ddsd.dwHeight); ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = 200; ddsd.dwHeight = 200; if (FAILED(hr = pdd->CreateSurface(&ddsd, &pddsBack, NULL))) { *piStepThatFailed = TESTID_CREATE_OFFSCREENPLAIN_SURFACE; goto LEnd; } SetRect(&rc, 0, 0, 32, 32); OffsetRect(&rc, 10, 35); ZeroMemory(&ddbltfx, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); for (i = 0; i < 200; i++) { ddbltfx.dwFillColor = 0; if (FAILED(hr = pddsBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx))) { *piStepThatFailed = TESTID_COLORFILL_BLT_TO_OFFSCREENPLAIN; goto LEnd; } OffsetRect(&rc, xv, yv); if (rc.left < 2 && xv < 0 || rc.right > 198 && xv > 0) xv = -xv; if (rc.top < 2 && yv < 0 || rc.bottom > 198 && yv > 0) yv = -yv; ddbltfx.dwFillColor = 0xffffffff; if (FAILED(hr = pddsBack->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx))) { *piStepThatFailed = TESTID_COLORFILL_BLT_TO_OFFSCREENPLAIN; goto LEnd; } SetRect(&rcDest, 0, 0, 200, 200); OffsetRect(&rcDest, (rcScreen.right - 200) / 2, (rcScreen.bottom - 200) / 2); if (FAILED(hr = pddsFront->Blt(&rcDest, pddsBack, NULL, DDBLT_WAIT, NULL))) { *piStepThatFailed = TESTID_BLT_OFFSCREENPLAIN_TO_FRONT; goto LEnd; } Sleep(2); } // Clean up affected screen area in case this display isn't part of the desktop: ddbltfx.dwFillColor = 0; if (FAILED(hr = pddsFront->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx))) { *piStepThatFailed = TESTID_COLORFILL_BLT_TO_PRIMARY; goto LEnd; } LEnd: InvalidateRect(NULL, NULL, FALSE); // repaint desktop ReleasePpo(&pddsBack); ReleasePpo(&pddsFront); return hr; } /**************************************************************************** * * TestFullscreen * ****************************************************************************/ HRESULT TestFullscreen(HWND hwndMain, LPDIRECTDRAW pdd, LONG* piStepThatFailed) { HRESULT hr; HWND hwnd = NULL; DDSURFACEDESC ddsd; LPDIRECTDRAWSURFACE pddsFront = NULL; LPDIRECTDRAWSURFACE pddsBack = NULL; RECT rc; RECT rcScreen; DDBLTFX ddbltfx; BOOL bDisplayModeSet = FALSE; INT i; LONG xv = 1; LONG yv = 2; ShowCursor(FALSE); if (FAILED(hr = CreateTestWindow(hwndMain, &hwnd))) { *piStepThatFailed = TESTID_CREATE_TEST_WINDOW; goto LEnd; } if (FAILED(hr = pdd->SetCooperativeLevel(hwnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN))) { *piStepThatFailed = TESTID_SETCOOPERATIVELEVEL_FULLSCREEN; goto LEnd; } if (FAILED(hr = pdd->SetDisplayMode(640, 480, 16))) { TCHAR szMessage[300]; TCHAR szTitle[100]; pdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL); SendMessage(hwnd, WM_CLOSE, 0, 0); LoadString(NULL, IDS_SETDISPLAYMODEFAILED, szMessage, 300); LoadString(NULL, IDS_APPFULLNAME, szTitle, 100); MessageBox(hwndMain, szMessage, szTitle, MB_OK); *piStepThatFailed = TESTID_SETDISPLAYMODE; goto LEnd; } bDisplayModeSet = TRUE; ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; if (FAILED(hr = pdd->CreateSurface(&ddsd, &pddsFront, NULL))) { *piStepThatFailed = TESTID_CREATEPRIMARYSURFACE_FLIP_ONEBACK; goto LEnd; } ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT; if (FAILED(hr = pddsFront->GetSurfaceDesc(&ddsd))) { *piStepThatFailed = TESTID_GETPRIMARYSURFACEDESC; goto LEnd; } SetRect(&rcScreen, 0, 0, ddsd.dwWidth, ddsd.dwHeight); ZeroMemory(&ddbltfx, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); DDSCAPS ddscaps; ddscaps.dwCaps = DDSCAPS_BACKBUFFER; if (FAILED(hr = pddsFront->GetAttachedSurface(&ddscaps, &pddsBack))) { *piStepThatFailed = TESTID_GETATTACHEDSURFACE; goto LEnd; } SetRect(&rc, 0, 0, 32, 32); OffsetRect(&rc, 10, 35); ZeroMemory(&ddbltfx, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); for (i = 0; i < 200; i++) { ddbltfx.dwFillColor = 0; if (FAILED(hr = pddsBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx))) { *piStepThatFailed = TESTID_COLORFILL_TO_BACKBUFFER; goto LEnd; } OffsetRect(&rc, xv, yv); if (rc.left < 2 && xv < 0 || rc.right > 198 && xv > 0) xv = -xv; if (rc.top < 2 && yv < 0 || rc.bottom > 198 && yv > 0) yv = -yv; OffsetRect(&rc, (rcScreen.right - 200) / 2, (rcScreen.bottom - 200) / 2); ddbltfx.dwFillColor = 0xffffffff; if (FAILED(hr = pddsBack->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx))) { *piStepThatFailed = TESTID_COLORFILL_TO_BACKBUFFER; goto LEnd; } OffsetRect(&rc, -(rcScreen.right - 200) / 2, -(rcScreen.bottom - 200) / 2); if (FAILED(hr = pddsFront->Flip(NULL, DDFLIP_WAIT))) { *piStepThatFailed = TESTID_FLIP; goto LEnd; } Sleep(2); } ddbltfx.dwFillColor = 0; if (FAILED(hr = pddsFront->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx))) { *piStepThatFailed = TESTID_COLORFILL_BLT_TO_PRIMARY; goto LEnd; } LEnd: ShowCursor(TRUE); ReleasePpo(&pddsBack); ReleasePpo(&pddsFront); if (FAILED(hr)) { // Something has already failed, so report that failure // rather than any failure of SetCooperativeLevel pdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL); } else { if (FAILED(hr = pdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL))) { *piStepThatFailed = TESTID_SETCOOPERATIVELEVEL_NORMAL; } } if (hwnd != NULL) SendMessage(hwnd, WM_CLOSE, 0, 0); if (bDisplayModeSet) { if (FAILED(hr)) { // Something has already failed, so report that failure // rather than any failure of RestoreDisplayMode pdd->RestoreDisplayMode(); } else { // Nothing has failed yet, so report any failure of RestoreDisplayMode if (FAILED(hr = pdd->RestoreDisplayMode())) return hr; } } return hr; } /**************************************************************************** * * CreateTestWindow * ****************************************************************************/ HRESULT CreateTestWindow(HWND hwndMain, HWND* phwnd) { static BOOL bClassRegistered = FALSE; WNDCLASS wndClass; TCHAR* pszClass = TEXT("DxDiag Test Window"); // Don't need to localize HINSTANCE hInst = (HINSTANCE)GetWindowLongPtr(hwndMain, GWLP_HINSTANCE); TCHAR szTitle[200]; if (!bClassRegistered) { ZeroMemory(&wndClass, sizeof(wndClass)); wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = DefWindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInst; wndClass.hIcon = NULL; wndClass.hCursor = NULL; wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = pszClass; if (NULL == RegisterClass(&wndClass)) return E_FAIL; bClassRegistered = TRUE; } LoadString(NULL, IDS_APPFULLNAME, szTitle, 200); *phwnd = CreateWindow(pszClass, szTitle, WS_OVERLAPPED, 0, 0, 0, 0, hwndMain, NULL, hInst, NULL); if (*phwnd == NULL) return E_FAIL; ShowWindow(*phwnd, SW_SHOW); return S_OK; }