Solved

DestroyWindow newby question.

Posted on 1998-12-02
12
278 Views
Last Modified: 2013-12-03
I have a simple test program that I have been using to develop a splash screen. There are two problems with it.

1. If I do a 'DestroyWindow' for the splash screen and then try to do a 'MessageBox' then the message box is not displayed (The function returns code 0x01). Any MessageBox before the DestroyWindow call works however.

2. If the splash screen is hidden by another window it is not re-painted when it is un-hidden.

The code that demonstrates these problems is:-

#include <windows.h>

HINSTANCE    hSplashInstance;
HINSTANCE    hSplashInst;
HWND            hSplashWnd;
HBITMAP        imgHandle;
BITMAP            gBitMap;

LRESULT CALLBACK SplashProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
      PAINTSTRUCT      ps;
      HDC                  hdc;
      HDC                  hDCMem;

      switch (message) {
      case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code here...
            hDCMem = CreateCompatibleDC(hdc);
            SelectObject(hDCMem, imgHandle);
            SetMapMode(hDCMem, GetMapMode(hdc));  
            // Draw the bitmap using the BitBlt function        
            if (BitBlt(
                  hdc,                // The destination device context
                  0, 0,               // Coordinates of the destination rectangle
                  gBitMap.bmWidth,   // Width of the dest. and source rectangle
                  gBitMap.bmHeight,// Height of the dest. and source rectangle
                  hDCMem, 0, 0, SRCCOPY)) {
                  DeleteDC(hDCMem);
            }

            RECT rt;
            GetClientRect(hWnd, &rt);

            EndPaint(hWnd, &ps);
            break;
      case WM_DESTROY:
            PostQuitMessage(0);
            break;
      default:
            return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}


BOOL InitSplashInstance(HINSTANCE hSplashInstance, int nCmdShow) {
      //
      imgHandle = (HBITMAP)LoadImage(NULL,"splash.bmp",NULL,NULL,NULL,LR_LOADFROMFILE);
      if (!imgHandle) {
            return FALSE;
      }
      GetObject(imgHandle, sizeof(BITMAP), &gBitMap);

      hSplashInst = hSplashInstance; // Store instance handle in our global variable



      hSplashWnd = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_DLGMODALFRAME |
       WS_EX_WINDOWEDGE, "SplashClass", NULL, WS_POPUP,
         (GetSystemMetrics(SM_CXSCREEN) - gBitMap.bmWidth) / 2,
         (GetSystemMetrics(SM_CYSCREEN) - gBitMap.bmHeight) / 2,
         gBitMap.bmWidth, gBitMap.bmHeight,
       NULL, NULL, hSplashInstance, NULL);
             
      if (!hSplashWnd) {
            return FALSE;
      }

      ShowWindow(hSplashWnd, nCmdShow);
      UpdateWindow(hSplashWnd);

      return TRUE;
}

ATOM SplashRegisterClass(HINSTANCE hSplashInstance) {
      WNDCLASSEX wcex;

      wcex.cbSize = sizeof(WNDCLASSEX);

      wcex.style = CS_HREDRAW | CS_VREDRAW;
      wcex.lpfnWndProc = (WNDPROC)SplashProc;
      wcex.cbClsExtra = 0;
      wcex.cbWndExtra = 0;
      wcex.hInstance = hSplashInstance;
      wcex.hIcon = NULL;
      wcex.hCursor = NULL;
      wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
      wcex.lpszMenuName = NULL;
      wcex.lpszClassName = "SplashClass";
      wcex.hIconSm = NULL;

      return RegisterClassEx(&wcex);
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow) {
      int      retval;

      // Create and display a SPLASH SCREEN
      SplashRegisterClass(hSplashInstance);
      if(!InitSplashInstance(hSplashInstance, nCmdShow)){
            return FALSE;
      }

      Sleep(2000);

      DestroyWindow(hSplashWnd);

      retval = MessageBox(NULL, "test message", "Diagnostics", MB_APPLMODAL|MB_ICONSTOP|MB_OK);
      Sleep(2000);

      return(0);
}
0
Comment
Question by:icd
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 3
12 Comments
 
LVL 5

Author Comment

by:icd
ID: 1416598
Edited text of question
0
 
LVL 11

Accepted Solution

by:
alexo earned 200 total points
ID: 1416599
Here's your problem:

    case WM_DESTROY:
        PostQuitMessage(0);

Lose the PostQuitMessage() call.  The PostQuitMessage function indicates to Windows that a thread has made a request to terminate (quit).  This is *not* what you need.
0
 
LVL 5

Author Comment

by:icd
ID: 1416600
alexo.

Thanks for that answer, it certainly answered the first part of my question.

As for the second part, do you have any idea how I can get the program to repaint my splash screen when it is un-hidden?
0
MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

 
LVL 11

Expert Comment

by:alexo
ID: 1416601
>> As for the second part [...]
Sorry, missed it.

Sleep(2000) is your problem.  While the thread is asleep, no message processing takes place.  Use a timer instead (SetTimer(), WM_TIMER and friends).
0
 
LVL 22

Expert Comment

by:nietod
ID: 1416602
Alex, it is a bigger problem than that.  He also needs a message loop for the splash screen.  Currently he displays the window, initializes the program, and destroys the window in a stream.  That is typical for splash windows, but it does make them rather unreactive.  To make it more reactive, you may need to start a 2nd thread for the splash window and provide it with a message loop.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1416603
>> He also needs a message loop for the splash screen
Right.  Where are my glasses?  :-)

>> To make it more reactive, you may need to start a 2nd thread for the splash window
Why a second thread?  Using a timer should be easier.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1416604
I was thinking a second thread that could handle its window messages why the 1st thread does its initialization and then destroys the splash window and thread.  However, I think I might need to clean my glasses as there is no evidence of any initialization going on as the splash window is displayed.  
0
 
LVL 5

Author Comment

by:icd
ID: 1416605
The sleep(2000) is to emulate my own (real) code which carries out several seconds of initialisation. I suspect that a second thread may be the only solution here since there will be no messages processed while I carry out my initialisation. Indeed I don't have a message loop in my (real) program at all since I don't (at least until now) need one!

0
 
LVL 11

Expert Comment

by:alexo
ID: 1416606
icd, you *should* have a message pump in your program for it to behave in a manner consistent with windows guidelines.  One example is DDE - if *any* running app is not processing messages, all DDE is blocked during this time.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1416607
And the autograder hits again!
0
 
LVL 22

Expert Comment

by:nietod
ID: 1416608
Did it just get autograded?  That is not 21 days.  Is there a Y2K-1 problem?
0
 
LVL 11

Expert Comment

by:alexo
ID: 1416609
Maybe EE changed the timeout?
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question