Several techniques of Visual C ++ programming-single instance and window style

Source: Internet
Author: User
Visual c ++ is an object-oriented visual programming tool that provides Appwizard to automatically generate applications. Program The standard framework greatly reduces 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 style of the default MDI Main Window includes fws_addtotitle. Composition File name), fws_prefixtitle (put the file name in front of 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 Code 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 a border 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, create the MFC Appwizard (exe) Framework application in the new dialog box that appears, 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 window client area, the title bar code is returned to Windows
// enables Windows to process the class on the title bar by mouse, you can click the move window
return (nhittest = htclient )? Htcaption: nhittest;
}< br> Method 2: When you press the left mouse button in the customer area of the window, 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 following code uses this method:
void cellipsewnddlg: onlbuttondown (uint nflags, cpoint point)
{< br> // call the parent class 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);
}< br> 5. allow an application to 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. One is how to find that an instance 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 initinstance, oncreate, and ondestroy function codes implement the preceding operations:
bool cellipsewndapp: initinstance ()
{< br> // 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: input a pointer to the policyicondata structure. The notifyicondata structure Declaration and the 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; // ID of the notification area icon
uint uflags; // indicates whether the following three items are meaningful
uint ucallbackmessage; // click the ID of the message sent by the icon
hicon; // The icon handle
char sztip [64]; // The prompt message displayed when you move the cursor over the icon
} notifyicondata, * pnotifyicondata;
when you use shell_policyicon to place an icon in the notification area of the task bar, a callback message is also defined. When you click or double-click the icon, the window handle specified in the notifyicondata 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.

Related Article

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.