One. statement of problem
A large number of shadow pop-up windows in Windows WinHelper Help systems, this window is very simple and has three-dimensional, they are used to display some read-only information. This pop-up window is different from the general window, they have no title And the rolling rod, but all have a shadow border, and the size of its window is automatically adjusted with the display string. When the display information is pop-up, any message from the keyboard or mouse will result in the disappearance of the pop-up window. However, there is no ready-made function in the Windows API interface to implement this feature, even the latest version of Visual C MFC does not provide ready-made classes and functions to implement such windows with shadows. To this end, the author is based on object-oriented programming idea, deriving a new class from CWND to implement this feature, and completely encapsulates all functions of the window, using just like calling "messagebox ()" function display information as simple as .
two. Several key parts of the implementation method are described below:
1. First, to solve how to paint non-user districts:
When Windows needs to create a window, it sends two messages: WM_NCPAINT and WM_PAINT to the application message queue. Wm_ncpain is used to redo the non-user area of the window, such as title, border, and rolling rod, this program is responsive to the border of the pop-up window with shadow; painting customer area is simple, just responding to WM_PAINT messaging characters The display can be displayed.
2. How to dynamically adjust the size of the pop-up window:
Everyone knows that when a text string is displayed in a rectangle, the common functions DrawText (HDC HDC, LPTSTSTSZTEXT, INT CBCOUNT, Rect Far * LPRECT, UINT FuFormat). However, at this time we have a shadow pop-up window and is established. Of course It can't be used to display. However, we noticed the last parameter fuFormat in the above functions, which is a combination of text format, which has a freshly known parameter dt_calcRect, use this parameter, the string does not display, but it is based on the current The font measures the height of the string to be displayed. This program is based on this parameter to determine the size of the pop-up window, and build a window with a string size, which gives it to implement this feature:
Void CshadowWnd :: ShowText (CString Stext)
{
......
CDC DC;
DC.CREATEDC ("Display", NULL, NULL, NULL); // Create a display device description table
Dc.selectObject (getStockObject); // Select font to device description table
CRECT RECT (0, 0, MaxWidth, 0); //
/ / Get the actual height and width of the string Stext to be displayed, and store it in a rectangular RECT
Dc.drawtext (Stext, Rect, DT_WordBreak | DT_Center | DT_CALCRECT | DT_NOPREFIX);
......
}
3. How to get control of the system:
After displaying the shadow pop-up display, how to obtain control of the system so that the user will disappear when the user will make the shadow pop-up window, the method taken here is that when the pop-up window is created and displayed After that, you will immediately enter a message loop, get all messages from the application queue, and determine if it is a mouse message or keyboard message, if it is destroyed to the end, and return the control to the calling program. Implement the pieces as follows:
// Enter the message loop, get all messages, control the entire system
......
MSG msg;
Bool bdone;
SetCapture ();
BDONE = false;
While (! bdone)
{
IF (PEEKMESSAGE (& MSG, NULL, 0, 0, PM_REMOVE))
IF (msg.Message == wm_keydown || msg.Message == WM_SYSKEYDOWN ||
Msg.Message == WM_LButtondown || msg.Message == WM_RBUTTONDOWN)
BDONE = TRUE;
Else
{
TRANSLATEMESSAGE (& MSG); DispatchMessage (& MSG);
}
}
Releasecapture ();
DESTROYWINDOW ();
......
}
Third. Head file with shadow CSHADOWND class and its implementation documents
//head File:
#if! defined (AFX_SHADOWND_H__B971A958_59CC_11D2_AC8F_0060084237F6__INCluded_)
#define AFX_SHADOWND_H__B971A958_59CC_11D2_AC8F_0060084237F6__included_
#iF _MSC_VER> = 1000
#pragma overce
#ENDIF / / _MSC_VER> = 1000
// ShadowWnd.h: Header File
//
/
// cshadowwnd window
Class CshadowWnd: Public CWnd
{
// construction
PUBLIC:
Cshadowwnd ();
// attributes
PUBLIC:
// Operations
PUBLIC:
// Overrides
// ClassWizard Generated Virtual Function Overrides
// {{AFX_VIRTUAL (CSHADOWND)
PUBLIC:
Virtual Bool Create (Const Rect & Rect, CWND * PParentWnd);
//}} AFX_VIRTUAL
// Implementation
PUBLIC:
CString m_sshowtext;
Void ShowReadOnlyText (CSTRING Stext);
CBRUSH M_BMPBRUSH;
Virtual ~ cshadowwnd ();
// generated message map functions
protected:
// {{AFX_MSG (cshadowwnd)
AFX_MSG void onncpaint ();
AFX_MSG void onpaint ();
AFX_MSG Int Oncreate (LPCReatestruct LPCreateStruct);
//}} AFX_MSG
Declare_message_map ()
}
/
// {{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio Will Insert Additional Declarations Immediate Line.
#ENDIF / /! Defined (AFX_SHADOWND_H___B971A958_59CC_11D2_AC8F_0060084237F6__inCluded_)
// Implement file
}
// ShadowWnd.cpp: Implementation File
//
#include "stdafx.h"
#include "shadow.h"
#include "shadowwnd.h"
#ifdef _Debug
#define new debug_new
#undef this_file
Static char this_file [] = __file__;
#ENDIF
// Define a constant
Static int apattern [] = {0xAA, 0x55, 0XAA, 0X55, 0XAA, 0X55, 0XAA, 0X55}; // Shadow bitmap array
#define spopup_shadowwidth 10 // Shadow width
#define spopup_shadowheight 13 // Shadow height
#define maxwidth 400 // Maximum width of the character rectangle /
// cshadowwnd
Cshadowwnd :: cshadowwnd ()
{
CBITMAP BMP;
Bmp.createBitmap (8, 8, 1, 1, (void *) apattern); // Create a shadow bitmap
m_Bmpbrush.createPatternbrush (& BMP); // Create a shadow brush
}
CshadowWnd :: ~ cshadowwnd ()
{
}
Begin_MESSAGE_MAP (CSHADOWND, CWND)
// {{AFX_MSG_MAP (cshadowwnd)
ON_WM_NCPAINT ()
ON_WM_PAINT ()
ON_WM_CREATE ()
//}} AFX_MSG_MAP
END_MESSAGE_MAP ()
/
// cshadowwnd message handlers
Bool CshadowWnd :: Create (const rect & Rect, cwnd * pparentwnd)
{
// Todo: Add Your Specialized Code Here and / or Call The Base Class
Const char * pclassname = AFXREGISTERWNDCLASS (CS_HREDRAW | CS_VREDRAW);
Return CWnd :: Createex (WS_EX_StativeEDGE, PCLASSNAME, "Shadow Window", WS_POPUP,
Rect.Left, Rect.top, Rect.right, Rect.Bottom,
PparentWnd-> GetsafehWnd (), 0, null;
}
Void cshadowwnd :: overncpaint ()
{
// Todo: Add your message Handler Code Here
CWindowDC DC (this);
CRECT RC;
GetWindowRect (& RC);
Rc.right- = rc.left; // width
Rc.bottom- = rc.top; // HEIGHT
rc.top = 0;
Rc.Left = 0;
M_Bmpbrush.unRealizeObject ();
CBRUSH * OLDBRUSH = DC.SelectObject (& m_Bmpbrush);
// Painting the shadow
Dc.patblt (rc.left spopup_shadowwidth, rc.bottom-spopup_shadowheight,
Rc.right-spopup_shadowwidth, spopup_shadowheight, patcopy;
// Painting the right side shadow
Dc.patblt (rc.right-spopup_shadowwidth, rc.top spopup_shadowheight,
Spopup_shadowwidth, rc.bottom, patcopy;
Dc.selectObject (Oldbrush); // restore old brush
CBRUSH * PBRUSH = CBRUSH :: fromHandle (GetsysColorbrush);
rc.right- = spopup_shadowwidth;
Rc.bottom- = spopup_shadowheight;
DC.FrameRect (RC, PBRUSH); // Section Box
// do not call cWnd :: overncpaint () for Painting Messages
}
Void cshadowwnd :: onpaint ()
{
CPAINTDC DC (this); // Device Context for Painting // Todo: Add Your Message Handler Code Here
CRECT RECT;
GetClientRect (& RECT);
Rect.Left = 5; Rect.top = 5;
Rect.right- = spopup_shadowwidth;
Rect.bottom- = spopup_shadowheight;
Dc.SetTextColor (RGB (0, 0, 255)); // Settings the text color
Dc.drawtext (m_sshowtext, rect, dt_wordbreak | dt_noprefix);
// do not call cWnd :: onpaint () for Painting Messages
}
Void cshadowwnd :: ShowReadOnlyText (CString Stext)
{
m_sshowtext = stext; // Deposits the display string
CDC DC;
DC.CREATEDC ("Display", NULL, NULL, NULL); // Create a display device description table
Dc.selectObject (getStockObject); // Select font to device description table
CRECT RECT (0, 0, MaxWidth, 0);
/ / Get the actual height and width of the string Stext to be displayed
Dc.drawtext (Stext, Rect, DT_WordBreak | DT_Center | DT_CALCRECT | DT_NOPREFIX);
/ / Remember some balance
Rect.right = 3 * spopup_shadowwidth;
Rect.bottom = 3 * spopup_shadowheight;
this-> Create (RECT, 0); // Creating a window
this-> showwindow (sw_show); // Display Window
this-> UpdateWindow (); // Immediately update the window
// Enter the message loop, get all messages, control the entire system
MSG msg;
Bool bdone;
SetCapture ();
BDONE = false;
While (! bdone)
{
IF (PEEKMESSAGE (& MSG, NULL, 0, 0, PM_REMOVE))
IF (msg.Message == wm_keydown || msg.Message == WM_SYSKEYDOWN ||
Msg.Message == WM_LButtondown || msg.Message == WM_RBUTTONDOWN)
BDONE = TRUE;
Else
{
TranslateMessage (& MSG);
DispatchMessage (& MSG);
}
}
Releasecapture ();
DESTROYWINDOW ();
}
Int cshadowwnd :: oncreate (lpcreateStruct lpcreatestruct)
{
IF (cwnd :: oncreate (lpcreatestruct) == -1)
Return -1;
// Todo: Add Your Specialized Creation Code Here
CenterWindow ();
Return 0;
}
Four. How to use:
1. Add this class to a project file
2. Add a member variable (such as: cshadowwnd m_shadowwnd) when you want to use a function (in the view class or frame window), when you need to use the shadow to display the message, call the member function (such as: m_shadowwnd) .ShowText (String Stext) can not consider it. Detail 5. Conclusion
This program compiled in the Visual C 5.0 environment.
This example also illustrates the programming of Windows, you must master the OOP method, and also reflect the powerful functionality of the Visual C MFC class library.