Implement Apple Window Interface in Windows95 / 98
High-wave Ma Yustry
Have you ever thought about realizing the style of Apple computer window interface in a Windows environment? Let's take a wonderful trip to the Apple computer window style.
Original
Carefully observe the Apple window, discovering the difference between the Windows window mainly reflects in the title bar and control button (ie minimizes, recovers, and off buttons). So we should focus on these two points and modify the Title Bar and Control Buttons of the Windows Window.
Since the title bar and control buttons belong to a non-client, the key is to obtain the CDC of the non-client area, which can be obtained by getWindowDC (). GetWindowDC () can get the CDC of the entire window, of course, also includes a CDC of a non-client area. After this CDC is obtained, the exact location of the title bar can be determined, and you can do it on the title bar. As shown in Figure 1, a bitmap is loaded in the title column (a bit chart intercepting the Apple window), add a text title on the bitmap (this title has 3D effect, it feels good, actually It is to write the same word twice with different colors and coordinates) and the control button (actually a bitmap, just display another bitmap when the mouse click, it looks like a button), Since the control button is your own, you must be responsible for clicking the button. To this end, although the title bar and button of the window are ready, there is no chance to display. We know that you want to paint Dongdong on the window of the window, just respond to Windows customer zone redraw messages, implement specific operations in this message processing function. Similarly, you must draw Dongdong in the non-client area, just respond to Windows's non-customer zone heavy-in messages, complete the title bar and buttons to complete the title bar and buttons.
Implementation
This technology is implemented in Windows 98 with VC6.0.
This method is described in detail below with a dialog box that generates an Apple Interface Style.
1. Generate a new application with AppWizard (SDI and MDI), add a Dialog resource in the Resource View.
2, add a new dialog class. Select to add a new class in ClassWizard, enter the class ctestdlg and select the base class cDialog. This establishs the connection between dialog boxes and dialog resources.
3, add button and title bar and background bitmap in Resource View.
Insert menu items in the main menu Select Resource, then select Add Bitmap, so you can see the Bitmap item in ResourceView, click on the right mouse button, select Import, select the apple style from existing bitmap files. Button and title bar, and give different IDs respectively.
4, add new buttons and new title bar in the CTestDLG class created.
(1) First mount the bitmap resource in the constructor of CTestDLG. The procedure is as follows:
Ctestdlg :: Ctestdlg (int NID,
CWND * pParent / * = null * /)
: Cdialog (NID, PPARENT)
{
// {{AFX_DATA_INIT (CTESTDLG)
// Note: The ClassWizard Will Add
MEMBER Initialization Here
//}} AFX_DATA_INIT
m_bpressed = false;
// load the bitmap of button_down
m_bitmappressed.loadbitmap (idb_buttondown);
// load the bitmap of button_upm_bitmapunpressed.loadbitmap (idb_buttle);
// load the bitmap of caption
m_bitmapcaption.loadBitmap (IDB_CAPTION);
// load the bitmap of background
m_bmpbk.loadbitmap (idb_bkground);
}
(2) Get the position of the title bar and button, respectively.
First get the location of the button:
Void ctestdlg :: getButtonRect (CRECT & RECT)
{
GetWindowRect (& Re);
// for small capensie sm_cydlgframe
Rect.top = getSystemMetrics 1;
// for small capensie sm_cysmsize
Rect.bottom = Rect.top GetSystemMetrics
(SM_Cysize) -4;
// for small capen use sm_cxdlgframe
Rect.Left = Rect.right -getsystemMetrics
(SM_CXFrame) -
// for small capensient use sm_cxsmsize
GetSystemMetrics - 1;
// for small capensient use sm_cxsmsize
Rect.right = Rect.Left GetSystemMetrics
(SM_CXSIZE) -3;
}
Then get the position of the title bar:
Void ctestdlg :: getCaptionRect (create & Re)
{
GetWindowRect (& Re);
// for small capensie sm_cysmsize
Rect.bottom = Rect.top GetSystemMetrics
(Sm_cysize) 3;
}
5. Draw an Apple style button and title bar at the corresponding position of the button and the title bar.
Draw a button first:
Void ctestdlg :: drawbutton ()
{
// if Window isn't visible or is minimized, SKIP
IF (! iswindowvisible () || isiconic ())
Return;
// Get Appropriate Bitmap
CDC MEMDC;
CDC * PDC = getWindowDC ();
MEMDC.CREATECOMPALEDC (PDC);
MEMDC.SELECTOBJECT (M_BPRESSED?
& M_bitmappressed: & m_bitmapunpressed);
// Get Button Rect and Convert IT IT INTO NON
-Client Area Coordinates
CRECT RECT, RECTWND;
GetButtonRect (RECT);
GetWindowRect (RectWnd);
Rect.offsetRect (-RectWnd.Left, -Rectwnd.top);
Int width, Height;
Bitmap * pbitmap;
Pbitmap = new bitmap; if (m_bpressed)
m_bitmappressed.getbitmap (PBITMAP);
Else
m_bitmapunpressed.getBitmap (Pbitmap);
Width = Pbitmap-> BMWIDTH;
Height = pbitmap-> bmheight;
// DRAW IT
PDC-> stretchblt (Rect.Lip, Rect.width (),
Rect.height (), & MEMDC, 0, 0,
Width, height, srccopy;
MEMDC.DELETEDC ();
ReleaseDC (PDC);
Delete pbitmap;
}
Then draw the title bar:
Void ctestdlg :: drawcaption ()
{
IF (! iswindowvisible () || isiconic ())
Return;
// Get Appropriate Bitmap
CDC MEMDC;
CDC * PDC = getWindowDC ();
MEMDC.CREATECOMPALEDC (PDC);
MEMDC.SELECTOBJECT (M_bitmapCAption);
// Get Button Rect and Convert IT IT INTO NON
-Client Area Coordinates
CRECT RECT, RECTWND;
GetCaptionRect (RECT);
GetWindowRect (RectWnd);
Rect.offsetRect (-RectWnd.Left, -Rectwnd.top);
// Draw the CAPTION
Int width, Height;
Bitmap * pbitmap;
Pbitmap = new bitmap;
m_bitmapcaption.getbitMap (PBITMAP);
Width = Pbitmap-> BMWIDTH;
Height = pbitmap-> bmheight;
PDC-> stretchblt (Rect.Lip, Rect.width (),
Rect.height (), & MEMDC, 0, 0, Width,
Height, Srccopy;
// Get the the text of the caption and
Draw it with 3D Style
PDC-> SetBkcolor (RGB (209, 209, 209);
CSTRING CAPTION;
GetWindowText (CAPTION);
CAPTION = " CAPTION " "
Rect.offsetRect (0, 4);
// Draw the Text of the Caption with Gray Color
PDC-> SetTextColor (RGB (128, 128, 128);
PDC-> DRAWTEXT
(CAPTION, RECT, DT_CENTER | DT_VCENTER);
//move the coordinate to Left and Up
Rect.offsetRect (-1, -1);
PDC-> setbkmode (transparent);
// Draw the Text of the Caption with White Color
PDC-> SetTextColor (RGB (255, 255, 255)); // 255, 255, 255 128, 128, 128
PDC-> DRAWTEXT
(CAPTION, RECT, DT_CENTER | DT_VCENTER);
MEMDC.DELETEDC ();
ReleaseDC (PDC);
Delete pbitmap;
}
6. Handling the message of the mouse click button.
To respond to the left mouse button click on the title bar, you need to add the corresponding message mapping function.
The effect of the button is pressed by changing the button in OnnclButtondown to change the button, and the window is closed.
Void ctestdlg :: ONNCLBUTTONDOWN
(Uint nhittest, cpoint point)
{
IF (nhittest == htcaption)
{
// See if IN area We Reserved for Button
CRECT RECT;
GetButtonRect (RECT);
IF (Rect.ptinRect (Point))
{
m_bpressed =! m_bpressed;
DrawButton ();
CDIALOG :: oncancel ();
}
}
CDIALOG :: OnnclButtondown (nhittest, point);
}
7. Handling the redraw between the non-customer area of the window.
Here is mainly a heavy blow to the title bar and buttons. Add the message mapping function of non-client zones to the dialog to add a non-client zone.
Void ctestdlg :: onncpaint ()
{
// Draw Caption First
CDIALOG :: OnncPaint ();
// Then Draw Button on TOP
Drawcaption ();
DrawButton ();
}
8. Add a background to the dialog box, here is a bitmap:
Void ctestdlg :: onpaint ()
{
CPAINTDC DC (this);
// Device Context for Painting
CDC MEMDC;
Memdc.createCompatibleDC (& DC);
MEMDC.SELECTOBJECT (M_BMPBK);
CRECT RECT, RECTWND
GetWindowRect (Rect);
GetClientRect (Rect);
Int width, Height;
Bitmap * pbitmap;
Pbitmap = new bitmap;
M_BMPBK.GetBitmap (PBITMAP);
Width = Pbitmap-> BMWIDTH;
Height = pbitmap-> bmheight;
Dc.stretchblt (Rect.LEFT, Rect.top, Rect.width (),
Rect.height (),
& MEMDC, 0, 0, Width, Height, Srccopy;
}
So far, a dialog with an apple window style is fresh! how about it? Is there a good taste?
However, if you have to use the dialog every time, isn't it too ... That! Don't panic, just try to change, you can once. This is as simple as the instructions for the constructor of this dialog box to the following black body. (Indicated by black body)
Ctestdlg :: Ctestdlg (int NID, CWND
* PParent / * = null * /)
: Cdialog (NID, PPARENT)
{
// {{AFX_DATA_INIT (CTESTDLG)
// Note: The ClassWizard Will Add
MEMBER Initialization Here
//}} AFX_DATA_INIT
m_bpressed = false;
m_bitmappressed.loadbitmap
(Idb_buttondown);
m_bitmapunpressed.loadbitmap
(Idb_buttonup);
m_bitmapcaption.loadBitmap (IDB_CAPTION);
m_bmpbk.loadbitmap (idb_bkground);
M_brushbutton.createsolidbrush
(RGB (192, 192, 255);
}
In the future, when using the dialog, set the dialog box in the VC's resource editor, change the parent class to this dialog box, of course, to include this dialog class, in your project, The dialog box shown in Figure 1 is inheritance in this dialog.
CDIALOG is changed to ctestdlg in CMYDIALOG.
Class CMYDIALOG: PUBLIC CTESTDLG
Void CNewapple1doc :: Ondialog1 ()
{
// Todo: add your command handler code here
CMYDIALOG DLG;
Dlg.domodal ();
}