Several Skills in Visual C ++ Programming

Source: Internet
Author: User
Visual c ++ is an object-oriented visual programming tool that provides Appwizard to automatically generate a standard framework for applications, greatly reducing the programming workload. This article describes the following programming skills: modify the main window style, create an irregular window, move the window outside the window title bar with the mouse, use the context menu, so that the application can run only one instance, so that the application is displayed as a task bar notification area icons and displayed rotating text.

1. Modify the main window style
The main window of the application framework generated by Appwizard has the default window style. For example, the document name is automatically added to the window title bar, the window is superimposed, and the window size can be changed. To modify the default window style, you must reload the cwnd: precreatewindow (createstruct & CS) function and modify the createstruct parameter CS.
The cwnd: precreatewindow function is executed before the window creation function. If the function is overloaded, the window creation function uses the window style defined by the createstruct CS parameter returned by the cwnd: precreatewindow function to create the window. Otherwise, the predefined window style is used.
The createstruct structure defines the initial parameters used to create the function creation window. The definitions are as follows:
Typedef struct tagcreatestruct {
Lpvoid lpcreateparams; // basic parameters of the Creation window
Handle hinstance; // has the module instance handle for the window to be created
Hmenu; // The menu handle of the new window
Hwnd hwndparent; // The parent window handle of the new window
Int Cy; // The height of the new window.
Int CX; // The width of the new window.
Int y; // y coordinate in the upper left corner of the new window
Int X; // The X coordinate in the upper left corner of the new window
Long style; // the style of the new window
Lpcstr lpszname; // name of the new window
Lpcstr lpszclass; // window class name of the new window
DWORD dwexstyle; // new window extension Parameters
} Createstruct;
The style field of the createstruct structure defines the style of the window. For example, the default MDI main window style includes fws_addtotitle (display the current work document name in the title bar) and fws_prefixtitle (put the document name before the program title), ws_thickframe (the window has a scalable border) and other styles. Because multiple style parameters are combined by logic or ("|"), to add a style, you only need to use "|" to add the corresponding parameters to the style domain of the createstruct structure; to delete an existing style, you need to connect the style field of the createstruct structure with the logical non-value of the style.
The X, Y, CX, and Cy fields of the createstruct structure define the initial position and size of the window respectively. Therefore, assign values to them in the cwnd: precreatewindow function, the initial display position and size of the window can be defined.
In the following example, the size of the window in the main box is fixed to 1/4. Only the window name is displayed in the title bar, but the document name is not displayed.
Bool cmainframe: precreatewindow (createstruct & CS)
{
// Todo: Modify the window class or styles here by modifying
// The createstruct CS

// Modify the main window style
CS. Style & = ~ Fws_addtotitle; remove the document name from the title bar
CS. Style & = ~ Ws_thickframe; remove the border that can be changed
CS. Style | = ws_dlgframe; add borders that cannot be changed

// Determine the size and initial position of the Main Window
Int cxscreen =: getsystemmetrics (sm_cxscreen); // obtain the screen width.
Int cyscreen =: getsystemmetrics (sm_cyscreen); // get the screen height
CS. x = 0; // The main window is located in the upper left corner.
CS. Y = 0;
CS. Cx = cxscreen/2; // The main window width is 1/2.
CS. Cy = cxscreen/2; // The main window height is 1/2.
Return cmdiframewnd: precreatewindow (CS );
}

2. Create an irregular window
Standard windows Windows. You can use the setjavaswrgn function of the cwnd class to create an irregular window.
The function prototype of cwnd: setjavaswrgn is as follows:
Int set0000wrgn (hrgn, // window area handle
Bool bredraw); // specifies whether to redraw the window.
The crgn class encapsulates data and operations on regions. The hrgn value can be obtained from the crgn class through the (hrgn) Force operation.
Crgn provides the createrectrgn, createellipticrgn, and createpolygonrgn member functions for creating rectangular, (elliptical) Circular, and polygon areas respectively.
The method for creating a non-rectangular window is as follows: first, define the area class member data (such as crgn m_rgnwnd) in the window class; secondly, call the createrectrgn, createellipticrgn, or createpolygonrgn function of the crgn class in the oncreate function of the window or the oninitdialog function of the dialog box to create the required region, and call the setjavaswrgn function.
In the following example, an elliptical window is generated.
1. Select the new command from the File menu in developer studio, and select create in the new dialog box that appears.MFCAppwizard (exe) Framework application, and enter the project name ellipsewnd. Set the application type to "dialog based". Other options are used to create project source files by default.
2. use the resource editor to delete all controls in the Main Dialog Box (ID: idd_ellipsewnd_dialog), and set the style to popup, untitled bar, and border from its properties dialog box (dialog properties.
3. In the ellipsewnddlg. H source file, add a crgn-type protected data member m_rgnwnd to the cellipsewnddlg of the Main Dialog Box class, which defines the window area.
4. In the ellipsewnddlg. cpp source file, modify the Main Dialog Box class cellipsewnddlg's oninitdialog () function, add m_rgnwnd creation, and define it as a window area. The bold statement is added.
Bool cellipsewnddlg: oninitdialog ()
{
Cdialog: oninitdialog ();
// Add "about..." menu item to system menu.
// Idm_aboutbox must be in the system command range.
Assert (idm_aboutbox & 0xfff0) = idm_aboutbox );
Assert (idm_aboutbox <0xf000 );

Cmenu * psysmenu = getsystemmenu (false );
If (psysmenu! = NULL)
{
Cstring straboutmenu;
Straboutmenu. loadstring (ids_aboutbox );
If (! Straboutmenu. isempty ())
{
Psysmenu-> appendmenu (mf_separator );
Psysmenu-> appendmenu (mf_string, idm_aboutbox,
Straboutmenu );
}
}

// Set the icon for this dialog. The framework does this automatically
// When the application's main window is not a dialog
Seticon (m_hicon, true); // set big icon
Seticon (m_hicon, false); // set small icon

// Set the window title to "elliptical window", although there is no title bar in the dialog box,
// However, the title is still required in the task bar button.
Setwindowtext (_ T ("elliptical window "));

// Obtain the screen width and height
Int cxscreen =: getsystemmetrics (sm_cxscreen );
Int cyscreen =: getsystemmetrics (sm_cyscreen );
// Set the radius of the ellipse in the X and Y directions
Int nellipsewidth = cxscreen/8;
Int nellipseheight = cyscreen/8;

// Set the window size to nellipsewidth and height to nellipseheight.
// And move it to the upper left corner
Movewindow (0, 0, nellipsewidth, nellipseheight );
// Create an elliptical area m_rgnwnd
M_rgnwnd.createellipticrgn (0, 0, nellipsewidth, nellipseheight );

// Set m_rgnwnd as the window area
Setjavaswrgn (hrgn) m_rgnwnd, true );

Return true; // return true unless you set the focus to a control
}

3. Move the window outside the window title bar with the mouse
You can move a standard window by clicking the title bar of the window. However, for a window without a title bar, you need to move the window outside the title bar by clicking the mouse. There are two ways to achieve this goal.
Method 1: when the window determines the mouse position, Windows sends the wm_nchittest message to the window to process the message, so that Windows considers the mouse over the title bar as long as the mouse is in the window. This requires the onnchittest function of the cwnd class to process the wm_nchittest message to call the function of the parent class in the function. If htclient is returned, it indicates that the cursor is in the window client area and the overload function returns htcaption, make windows mistakenly think that the mouse is on the title bar.
The following example shows the actual code that uses this method:
Uint cellipsewnddlg: onnchittest (cpoint point)
{
// Obtain the window area where the mouse is located
Uint nhittest = cdialog: onnchittest (point );

// If the mouse is in the client area of the window, the title bar code is returned to Windows
// Enables Windows to process the class on the title bar by mouse, and you can click to move the window.
Return (nhittest = htclient )? Htcaption: nhittest;
}
Method 2: When you press the left mouse button in the window client area, Windows considers the mouse to be on the title bar, that is, the onlbuttondown function that processes the wm_lbuttondown message sends a wparam parameter htcaption, and lparam is the wm_nclbuttondown message of the current coordinate.
The actual code for using this method is as follows:
Void cellipsewnddlg: onlbuttondown (uint nflags, cpoint point)
{
// Call the parent handler to complete basic operations
Cdialog: onlbuttondown (nflags, point );

// Send the wm_nclbuttondown message
// Make windows think that the mouse is on the title bar
Postmessage (wm_nclbuttondown,
Htcaption,
Makelparam (point. X, point. y ));
}

4. Use context menu
Windows 95 applications support the context menu function by right-clicking the context menu, which can be achieved by processing the wm_contextmenu message.
When you right-click the message in the window, the window receives the wm_contextmenu message, loads the context menu in the message processing function, and calls the cmenu: trackpopupmenu function to display the context menu. Cmenu: the prototype of the trackpopupmenu function is as follows:
Bool trackpopupmenu (uint nflags, // display and Selection Method flag
Int X, int y, // display the coordinates in the upper left corner of the menu
Cwnd * pwnd, // window object for receiving menu operations
Lpcrect lprect = NULL); // sensitive area
To use the context menu, you should first compile the context menu in the resource editor. Assume that the context menu is named idr_menu_context. Secondly, use classwizard to add the oncontextmenu function for the window to process the message wm_contextmenu, and the processing functions of each menu command; then write the corresponding code.
The following is an example of the oncontextmenu function code:
Void cellipsewnddlg: oncontextmenu (cwnd * pwnd, cpoint point)
{
Cmenu menu;

// Load menu
Menu. loadmenu (idr_menu_context );

// Display menu
Menu. getsubmenu (0)-> trackpopupmenu (
Tpm_leftalign | tpm_leftbutton | tpm_rightbutton,
Point. X, point. Y, this );
}

5. Make the application run only one instance
Windows is a multi-process operating system. Applications generated by the framework can run multiple times to form multiple running instances. However, in some cases, to ensure the secure operation of applications, the program must run only one instance. For example, if the program needs to use special hardware (such as a modem) that can only be used separately by one process, you must restrict the program to run only one instance.
There are two basic problems involved: first, how to find that an existing instance of the program is running when the second instance of the program is started, but how to activate the first instance, the second instance exits.
For the first problem, you can set a semaphore for the application. When the instance starts, it first detects the semaphore. If the semaphore already exists, it indicates that the program has run an instance.
The second difficulty is to obtain the main window object pointer or handle of the first instance, and then use setforegroundwindow to activate it. Although the findwindow function can find a window that is running, the function requires that the title or Class Name of the window to be searched be specified, which is not a common method. We can use the setprop function of Win 32 SDK to set a unique tag for the main window of the application. You can use getdomaintopwindow to obtain the object pointer or handle of the Windows main control window. All application main windows can be seen as subwindows of the window. You can use the getwindow function to obtain their object pointers or handles. Use the getprop function of the Win 32 SDK to check whether the main window of each application contains the specific tag we set to determine whether the main window of the instance is the first one we are looking. It is easy to exit the second instance, as long as the initinstance function of Its Application Object returns false. In addition, when the main window exits, the removeprop function is applied to delete the tag we set for it.
The following code of the initinstance, oncreate, and ondestroy functions implements the preceding operations:
Bool cellipsewndapp: initinstance ()
{
// Create a semaphore with the application name
Handle hsem = createsemaphore (null, 1, 1, m_pszexename );

// The semaphore already exists?
// If the semaphore exists, the program already has an instance running
If (getlasterror () = error_already_exists)
{
// Close the semaphore handle
Closehandle (hsem );

// Find the main window of the previous instance
Hwnd hwndprevious =: getwindow (: get1_topwindow (), gw_child );
While (: iswindow (hwndprevious ))
{
// Check whether there is a preset flag in the window?
// If yes, it is the main window we are looking
If (: getprop (hwndprevious, m_pszexename ))
{
// Restore the size of the main window if it is minimized.
If (: isiconic (hwndprevious ))
: Showwindow (hwndprevious, sw_restore );
// Activate the Main Window
: Setforegroundwindow (hwndprevious );
// Activate the dialog box of the Main Window
: Setforegroundwindow (: getlastactivepopup (hwndprevious ));

// Exit the instance
Return false;
}

// Continue searching for the next window
Hwndprevious =: getwindow (hwndprevious, gw_hwndnext );
}

// The previous instance already exists, but the main window cannot be found
// An error may occur.
// Exit the instance
Return false;
}

Afxenablecontrolcontainer ();

// Standard Initialization
// If you are not using these features and wish to reduce the size
// Of your final executable, you should remove from the following
// The specific initialization routines you do not need.

# Ifdef _ afxdll
Enable3dcontrols (); // call this when using MFC in a shared DLL
# Else
Enable3dcontrolsstatic (); // call this when linking to MFC statically
# Endif

Cellipsewnddlg DLG;
M_pmainwnd = & DLG;
Int nresponse = DLG. domodal ();
If (nresponse = idok)
{
// Todo: Place code here to handle when the dialog is
// Dismissed with OK
}
Else if (nresponse = idcancel)
{
// Todo: Place code here to handle when the dialog is
// Dismissed with cancel
}

// Since the dialog has been closed, return false so that we exit
// Application, rather than start the application's message pump.
Return false;
}

Int cellipsewnddlg: oncreate (maid)
{
If (cdialog: oncreate (lpcreatestruct) =-1)
Return-1;

// Set the search tag
: Setprop (m_hwnd, afxgetapp ()-> m_pszexename, (handle) 1 );

Return 0;
}

Void cellipsewnddlg: ondestroy ()
{
Cdialog: ondestroy ();

// Delete the search tag
: Removeprop (m_hwnd, afxgetapp ()-> m_pszexename );
}

6. display the application as an icon in the task bar notification area
On the right side of the Windows 95 job bar, there is an area called the notification area. Some Application icons are displayed. You can click the icons to display the application menu, double-click to display the complete window of the application. Clock and volume control are the most common icons in the task bar notification area.
Task Bar notification area programming can be implemented through the shell_policyicon function of the Windows 95 shell programming interface. This function is declared in the shellapi. h header file, and its prototype is as follows:
Winshellapi bool winapi shell_policyicon (DWORD dwmessage,
Pnotifyicondata pnid );
Dwmessage is a message that operates on the icon in the notification area. It is mainly composed of three parts, as shown in the following table.
Messages used by shell_policyicon
Message
Description
Nim_add
Insert an icon in the task bar notification area
Nim _ Delete
Delete an icon in the task bar notification area
Nim _ modify
Modify the icon of the task bar notification area

Pnid is used to input a pointer to the policyicondata structure. The notifyicondata structure declaration and meanings of each domain are as follows:
Typedef struct _ policyicondata {// Nid
DWORD cbsize; // number of bytes in the notifyicondata Structure
Hwnd; // handle the window for processing the notification area icon message
Uint uid; // the ID of the notification area icon
Uint uflags; // indicates whether the following three items are meaningful.
Uint ucallbackmessage; // the ID of the message sent by clicking the mouse
Hicon; // icon handle
Char sztip [64]; // The prompt message displayed when you move the cursor over the icon
} Notifyicondata, * ppolicyicondata;
When shell_policyicon is used to place an icon in the task bar notification area, a callback message is also defined. When you click or double-click the icon with the mouse, the window handle specified in the policyicondata structure will receive the message. The lparam parameter of the message describes the mouse operation method. When the application exits, delete the icon in the task bar.

The following example shows how to display the aforementioned elliptical window program as an icon in the task bar notification area. When you click the icon, a menu is displayed, the elliptical window is displayed completely.
1. Use the resource editor to add a menu item "insert icon in Task Bar" (ID: idm_inserticon) to the idr_menu_context menu of the ellipsewnd project ).
2. Use the resource editor to add a menu resource idr_menu_icon to the ellipsewnd project and set three menu items:
"Activate elliptical window" (ID: idm_activewindow)
"About..." (ID: idm_aboutbox)
"Exit Alt + F4" (ID: idm_exit)
3. Define a message um_iconnotify in the cellipsewnddlg. H source file to respond to the icon operation, and add oniconnotify to the cellipsewnddlg class definition. Use classwizard to add the function definitions and templates of the response menu commands idm_inserticon and idm_activewindow. Modify cellipsewnddlg. h as follows:

// Define the response icon operation message
# Define um_icon1_y wm_user + 100

Class cellipsewnddlg: Public cdialog
{
// Construction
Public:
Cellipsewnddlg (cwnd * pparent = NULL); // standard Constructor

// Dialog data
File: // {afx_data (cellipsewnddlg)
Enum {IDD = idd_ellipsewnd_dialog };
// Note: The classwizard will add data members here
File: //} afx_data

// Classwizard generated virtual function overrides
File: // {afx_virtual (cellipsewnddlg)
Protected:
Virtual void dodataexchange (cdataexchange * PDX); // DDX/DDV support
File: //} afx_virtual

// Implementation
Protected:
Hicon m_hicon;
Crgn m_rgnwnd;

// Function Description of the processing icon
Bool addicon ();
Bool deleteicon ();

// Generated message map Functions
File: // {afx_msg (cellipsewnddlg)
Virtual bool oninitdialog ();
Afx_msg void onsyscommand (uint NID, lparam );
Afx_msg void onpaint ();
Afx_msg hcursor onquerydragicon ();
Afx_msg void onlbuttondown (uint nflags, cpoint point );
Afx_msg void oncontextmenu (cwnd * pwnd, cpoint point );
Afx_msg void onaboutbox ();
Afx_msg void onexit ();
Afx_msg int oncreate (maid );
Afx_msg void ondestroy ();
Afx_msg void oninserticon ();
Afx_msg void onactivewindow ();
File: //} afx_msg
// Function Description of icon Message Processing
Afx_msg void oniconnotify (wparam, lparam );
Declare_message_map ()
};

4. Add the following message shot entries to cellipsewnddlg. cpp:
Begin_message_map (cellipsewnddlg, cdialog)
File: // {afx_msg_map (cellipsewnddlg)
On_wm_syscommand ()
On_wm_paint ()
On_wm_querydragicon ()
On_wm_lbuttondown ()
On_wm_contextmenu ()
On_command (idm_aboutbox, onaboutbox)
On_command (idm_exit, onexit)
On_wm_create ()
On_wm_destroy ()
On_command (idm_inserticon, oninserticon)
On_command (idm_activewindow, onactivewindow)
File: //} afx_msg_map
On_message (um_iconnotify, oniconnotify)
End_message_map ()

5. Add the following function or code to cellipsewnddlg. cpp:
Void cellipsewnddlg: ondestroy ()
{
Cdialog: ondestroy ();

// Remove Main Window tag
: Removeprop (m_hwnd, afxgetapp ()-> m_pszexename );

// When the application exits, delete the icon in the task bar
Deleteicon ();
}

Bool cellipsewnddlg: addicon ()
{
// Add an icon to the task bar
Notifyicondata NID;
Nid. cbsize = sizeof (NID );
Nid. hwnd = m_hwnd;
Nid. uid = idr_mainframe;
Nid. uflags = nif_message | nif_icon | nif_tip;
Nid. ucallbackmessage = um_iconnotify;
Nid. hicon = m_hicon;
Cstring STR = "elliptical window ";
Lstrcpyn (NID. sztip, (lpcstr) STR,
Sizeof (NID. sztip)/sizeof (NID. sztip [0]);

Return shell_policyicon (nim_add, & nid );
}

Bool cellipsewnddlg: deleteicon ()
{
// Delete the icon in the task bar
Notifyicondata NID;
Nid. cbsize = sizeof (NID );
Nid. hwnd = m_hwnd;
Nid. uid = idr_mainframe;

Return shell_policyicon (nim_delete, & nid );
}

// Response icon Message Processing Function
Void cellipsewnddlg: oniconnotify (wparam,
Lparam)
{
Switch (uint) lparam)
{
// Click the mouse
Case wm_lbuttondown:
Case wm_rbuttondown:
{
// Mount the icon operation menu
Cmenu menu;
Menu. loadmenu (idr_menu_icon );

// The cursor position
Cpoint point;
Getcursorpos (& Point );

// Activate the background window
Setforegroundwindow ();

// Display the icon menu
Menu. getsubmenu (0)-> trackpopupmenu (
Tpm_leftbutton | tpm_rightbutton,
Point. X, point. Y, this, null );

// Add an additional message to make the menu operation correct
Postmessage (wm_user, 0, 0 );
Break;
}
// Double-click
Case wm_lbuttondblclk:
// Activate the application
Onactivewindow ();
Break;
}
}

// Insert the icon to the task bar notification area
Void cellipsewnddlg: oninserticon ()
{
// Hide the main window first
Showwindow (sw_hide );
// Insert icon
Addicon ();
}

// Activate the Main Window
Void cellipsewnddlg: onactivewindow ()
{
// Delete the icon first
Deleteicon ();
// Display the Main Window
Showwindow (sw_show );
Updatewindow ();
}

7. Display rotating text
In some applications, in order to achieve special effects, it is often necessary to display the rotated text. The text display mode, including rotation, is set by the font.
The font attribute is mainly defined by the logfont structure used when the font is created. The lfescapement field in this structure specifies the angle of the text line and the X axis (horizontal axis), and the angle unit is 10 in units. To rotate all fonts in the same direction, set the lfclipprecision field of the logfont structure to clip_lh_angles.
The following code displays a line of text every 15 degrees at the same start point in the dialog box:
Void crotatetextdlg: onpaint ()
{
Cpaintdc DC (this); // device context for painting

If (isiconic ())
{
Sendmessage (wm_iconerasebkgnd, (wparam) DC. getsafehdc (), 0 );

// Center icon in client rectangle
Int cxicon = getsystemmetrics (sm_cxicon );
Int cyicon = getsystemmetrics (sm_cyicon );
Crect rect;
Getclientrect (& rect );
Int x = (rect. Width ()-cxicon + 1)/2;
Int y = (rect. Height ()-cyicon + 1)/2;

// Draw the icon
DC. drawicon (X, Y, m_hicon );
}
Else
{
Crect RC;
Getclientrect (RC );

Cstring STR (_ T ("...... rotate text! "));

DC. setbkmode (transparent );
DC. settextcolor (RGB (0, 0, 255 ));

Cfont font;
Logfont lf;
Memset (& lf, 0, sizeof (logfont ));

Lf. lfheight =-14;
Lf. lfweight = fw_normal;
Lf. lfclipprecision = clip_lh_angles;
Strcpy (LF. lffacename, "");

For (INT I = 0; I <3600; I + = 150)
{
Lf. lfescapement = I;

Font. createfontindirect (& lf );
Cfont * poldfont = Dc. SelectObject (& font );

DC. textout (RC. Right/2, RC. Bottom/2, STR );

DC. SelectObject (poldfont );
Font. deleteobject ();
}

Cdialog: onpaint ();
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.