0

I'm working on an Windows Application which has to show an overlaying fixed positioned window ("PopUp") in the left corner of the MainFrame which will receive some Information if a user missed some input or if certain actions have been successfully.

The "PopUp" Titlebar shall have an Icon next to the Title (e.g. ->Icon<- "Error") and the standard X - Close-Button. The ClientArea will have an descriptive text of the occurred Message.

Additionally the standard Border of the PopUp shall be set to 1px(smaller than the default windows border)

The "PopUp" is derived from CWnd and created with WS_VISLBE | WS_CLIPSIBLINGS | WS_CHILD | WS_CAPTION in the OnCreate-Method of the Applications MainFrame Window

Now I need to set/shrink the default Border of my PopUp and add the Icon to the Titlebar of the PopUp.

Can someone give me some example code of how i can solve my issues? I'm pretty new to c++ and MFC so far my research brought me to https://msdn.microsoft.com/en-us/library/windows/desktop/bb688195(v=vs.85).aspx but i dont know where and how to use DwmExtendFrameIntoClientArea() but so far I've read I assume Dwm is the way to go to be able to solve both problems or is there another/totally different way? Am I on the right track?

Jan Raufelder
  • 287
  • 7
  • 23
  • A window with the `WS_CHILD` window style is a child window. A child window is the opposite of a popup window (see [Window Types](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632599.aspx#types)). It's unclear, what you really want. – IInspectable May 31 '16 at 09:46
  • I know that WS_CHILD != WS_POPUP thats why i always put it in quotes to indicate that this is only a name and not a style... I've chosen WS_CHILD cause the Window("PopUp") needs to be always within in the MainFrame Window. It can be opened by a ButtonClick in the Statusbar and will overlay the bottom left area of the Main Frames Client Area. Everything in the Mainframe but the overlayed part will still be clickable. For that Window("PopUp") the titlebar needs an Icon and the default Window Borders to the left bottom and right set to 1px – Jan Raufelder May 31 '16 at 10:36
  • check http://stackoverflow.com/questions/410720/can-i-change-the-thickness-of-the-border-of-a-window-with-mfc?rq=1 The OP has the same aim as I do, but unfortunatly the answer provided gives only hints where to start of but no code samples. (I do not know which members i need to manipulate in WM_NCPAINT to archive my goals) – Jan Raufelder May 31 '16 at 15:45
  • How about using a normal dialog window and placing it in the desired area? The normal dialog provides icon and title and the system buttons (min/max/close), but you can manipulate that. Instead of going modal, use an interface or common dialog class or some message/event from your main window to determine which child window is getting active(clicking/activating brings them to the top). Allow click events/messasges, but process activation messages to keep the desired child window topmost. – PRinCEKtd Jun 01 '16 at 04:50

1 Answers1

3

Finally I was able to shrinkthe default Windows Border by overriding the handling of WM_NCCALCSIZE.

I will update this answer as soon as I solved how to put my Icon in the Titlebar. As of now I'll explain how I shrink the windows border:

Add ON_WM_NCCALCSIZE() to your MessageMap of the desired Window and Implement OnNcCalcSize() (Class Wizard will help to set this up) as followed:

void YourCWndClass::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{

   if (bCalcValidRects){   
      CRect rcClient, rcWind;
      GetClientRect(&rcClient);
      GetWindowRect(&rcWind);


      int border = (rcWind.right - rcWind.left - rcClient.right) / 2 - 1;
      //-1: leaves 1px of the Windows Default Border Width erase to have no border

      lpncsp->rgrc->left -= border;
      lpncsp->rgrc->right += border;
      lpncsp->rgrc->bottom += border;
   }

   CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
}

The WM_NCCALCSIZE Message is sent up on the Window Creation (when you call Create()/CreateEx() ) but at this point of time GetClientRect() and GetWindowRect() will not return the proper values therefore you need to check the Bool Parameter!!!

To trigger another WM_NCCALCSIZE to be able to work with the proper Window Rectangles call SetWindowPos() right after the window creation

if (!m_MessagePopOver->Create(NULL, NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CAPTION, rect, this, NULL, NULL)){
      TRACE0("failed to create MessagePopOver");
   }

m_MessagePopOver->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

This will result in a window like this:

rounded windowframe illustration

Gunther Struyf
  • 11,158
  • 2
  • 34
  • 58
Jan Raufelder
  • 287
  • 7
  • 23