Winmain/unreferenced_parameter/hpreinstance

Source: Internet
Author: User
Tags old windows

# Include <window. h>
# Include "resource"
# Include "Generic. H"
Hinstance _ hinst;
Hwnd _ hwnd;
Char _ szappname [] = "generic ";
Char _ sztitle [] = "generic sample application ";
Int callback winmain (hinstance, // detailed introduction
Hinstance hprevinstance,
Lpstr lpcmdline,
Int ncmdshow)
{
MSG;
Unreferenced_parameter (lpcmdline); // detailed description
If (! Hprevinstance) // detailed description
If (! Initapplication (hinstance ))
Return (false );
If (! Intitinstance (hinstance, n1_sow ))
Return (false );
While (getmessage (& MSG, null, 0, 0 )){
Translatemessage (& MSG );
Dispatchmessage (& MSG );
}
Return (msg. wparam );
}
Bool initapplication (hinstance)
{
WC. Style = cs_hredraw | cs_vredraw;
WC. lpfnwndproc = (wndproc) wndproc ;/////////////////////////////
WC. cbclsextra = 0;
WC. cbwndextra = 0;
WC. hinstance = hinstance;
WC. hicon = loadicon (hinstance, "jjhouricon ");
WC. hcursor = loadcursor (null, idc_arrow );
WC. hbrbackground = getstockobject (white_brush); // background color of the hidden window
WC. lpszmenuname = "genericmenu"; // The table specified by. RC
WC. lpszclassname = _ szappname;

Return (registerclass (& WC ));
// Initinstance-production window
//---------------------------------------------------------------------
Bool initinstance (hinstance, int ncmdshow)
{
_ Hinst = hinstance; // The region is saved as a global variable for ease of use.

_ Hwnd = createwindow (
_ Szappname ,////////
_ Sztitle ,//////////////
Ws_overlappedwindow,
Cw_usedefault,
Cw_usedefault,
Cw_usedefault,
Cw_usedefault,
Null,
Null,
Hinstance,
Null
);

If (! _ Hwnd)
Return (false );

Showwindow (_ hwnd, ncmdshow); // display the rows window
Updatewindow (_ hwnd); // sends wm_paint
Return (true );

}
//---------------------------------------------------------------------
// Wndproc-example Window Function
//---------------------------------------------------------------------
Lresult callback wndproc (hwnd,
Uint message,
Wparam ,//
Lparam)

{
Int wmid, wmenent;
Switch (Message ){
Case wm_command:
Wnid = lpword (wparam); // command ID
Wmevent = hiword (wparam );
Switch (wmid ){
Case idm_about:
Dialogbox (_ hinst,
"Aboutbox", // The Source Name of the conversation box
Hwnd, // parent window
(Dlgproc) about // conversation box function name callback
);
Break;

Case idm_exit:
// The user wants to end the program. The processing method is the same as that of wm_close.
Destroywindow (hwnd );
Break;

Default:
Return (defwindowproc (hwnd, message, wparam, lparam ));
}
Break;

Case wm_destroy: // The window has been destroyed (the program is about to end ).
Postquitmessage (0 );
Break;

Default:
Return (defwindowproc (hwnd, message, wparam, lparam ));
}
Return (0 );
}
//---------------------------------------------------------------------
// About-conversation box function
//---------------------------------------------------------------------
Lresult callback about (hwnd hdlg, uint message,
Wparam, lparam)
{
Unreferenced_parameter (lparam); // avoid warnings during the specified period.

Switch (Message ){
Case wm_initdialog:
Return (true); // true indicates that I have handled the response.

Case wm_command:
If (loword (wparam) = idok
| Loword (wparam) = idcancel ){
Enddialog (hdlg, true );
Return (true); // true indicates that I have handled the response.
}
Break;
}
Return (false); // false indicates that I have not handled this alarm.
}

 

Int winapi winmain (hinstance, hinstance hprevinstance, lpstr lpcmdline, int ncmdshow)
{
Return (0 );
}

A function should return a value even if nothing is done. Yes. We are not familiar with many things. First, what is the declaration of winapi? Winapi is a macro defined in the windows. h header file. It translates function calls into correct call conventions. When we need to use the assembly language in the program, let's take a deeper look at it. Remember, if we want to use winmain (), we must have winapi.

Next, let's take a look at the four parameters in brackets:

◎ Hinstance: hinstance is a handle type identifier. The variable hinstance is an integer used to identify the program instance. In Windows, set the value of this parameter and pass it to your program code. Many Windows functions need to use it.

◎ Hinstance hpreinstance: You don't have to worry about this parameter. It has been scrapped. It only serves the old Windows version. You will see a similar situation.

◎ Lpstr lpcmdline: a pointer to a string. It takes effect only when the program name is input from the doscommand line or from the run dialog box. Therefore, it is rarely used by program code.

◎ Int ncmdshow: determines the initial display status of the window. Windows usually assigns a value to this parameter. It is usually a constant starting with SW. For example, sw_shownormal indicates the default state, and sw_maxinize or sw_minimize indicates the maximum and minimum modes, respectively.





++ At work column...
Parameters not referenced, add the taskbar command and other...

Original: Paul dilascia
Translation: northtibet

Download source code: catwork0505.exe (171kb)
Source: unreferenced parameters, adding Task Bar commands, and more

Parameters not referenced
Add taskbar command

I have seen some C ++ codes use unreferenced_parameter for unused parameters, for example:

int SomeFunction(int arg1, int arg2){  UNREFERENCED_PARAMETER(arg2)  ...}

I have also seen such code:

int SomeFunction(int arg1, int /* arg2 */){  ...}

Can you explain their differences? Which method is better? Judy mcgeough

Yes! Why? Let's start with unreferenced_parameter. This macro is defined in winnt. h as follows:

#define UNREFERENCED_PARAMETER(P) (P)

In other words, unreferenced_parameter expands the passed parameter or expression. The purpose is to prevent the compiler from warning about unreferenced parameters. Many programmers, including me, prefer to compile with the highest level warning level 4 (/W4. Level 4 belongs to the scope of "events that can be safely ignored. Although they may embarrass you, they seldom corrupt your code. For example, there may be some code lines in your program:

int x=1;

But you have never used X. Maybe this line was left behind when you used X before. You only deleted the code that used it and forgot to delete the variable. Warning Level 4 can find these minor issues. So, why not let the compiler help you achieve the highest level of specialization? Compiling with Level 4 is a way to show your work attitude. If you write a library for public users, Level 4 is required for social etiquette. You don't want to force your developers to use low-level options to cleanly compile their code.
The problem is that level 4 really pays too much attention to the details. on Level 4, the compiler will complain about anything that does not reference a parameter (unless you are really interested in using this parameter, ). Suppose you have a function that brings two parameters, but you only use one of them:

int SomeFunction(int arg1, int arg2){    return arg1+5;}

When using/W4, the compiler complains:

“warning C4100: ''arg2'' : unreferenced formal parameter.”

To cheat the compiler, you can add unreferenced_parameter (arg2 ). Now the compiler will shut down when compiling your function that references arg2. And because of the statement:

arg2;

In fact, the compiler will not generate any code for it, so there will be no loss in space and performance.

Careful people may ask: Since you do not use arg2, why should you declare it? It is usually because you implement a function to meet the inherent signature requirements of Some APIs. For example, the onsize processing routine of MFC must be like the following:

void OnSize(UINT nType, int cx, int cy);

Here, CX/Cy is the new width/height of the window, and ntype is an encoding similar to size_maximized or size_restored, indicating whether the window is maximized or the regular size. Generally, you don't care about ntype, but only focus on CX and XY. So if you want to use/W4, you must use unreferenced_parameter (ntype ). Onsize is only one of thousands of MFC and Windows functions. Writing a Windows-based program makes it almost impossible to encounter unreferenced parameters.
So much about unreferenced_parameter. In her question, Judy also mentioned another common C ++ programmer and its role is the same as that of unreferenced_parameter, that is, the parameter name in the annotation function signature:

void CMyWnd::OnSize(UINT /* nType */, int cx, int cy){}

Now ntype is an unnamed parameter, and the effect is the same as if you typed onsize (uint, int CX, int CY. Now the key question is: which method should you use -- unnamed parameter or unreferenced_parameter?
In most cases, there is no difference between the two. Which one is purely a style issue. (Do you like your java coffee in black or cream color ?) However, I think at least one case must use unreferenced_parameter. Suppose you decide that the window cannot be maximized. You can disable the maximize button to delete it from the system menu and prevent each user from maximizing the window. Because you are paranoid (most good programmers are paranoid), you add an assert to ensure that the code runs according to your intent:

void CMyWnd::OnSize(UINT nType, int cx, int cy){    ASSERT(nType != SIZE_MAXIMIZE);    ... // use cx, cy}

The QA Team has tried its best to run your program in various ways. The assert has never been popped up, so you think it is safe to compile the release version. However, the _ debug definition does not exist at this time. Assert (ntype! = Size_maximize) expands to (void) 0), and ntype becomes an unreferenced parameter at once! In this way, you can perform a clean compilation. You cannot comment out the ntype In the parameter table because you need to use it in assert. In this case, the only parameter you use is in assert or other _ debug condition code. Only unreferenced_parameter will keep the compiler in debug and release generation modes. Do you know?
Before closing the discussion, I think there is another problem I did not mention, that is, you can use the Pragma command to suppress a single compiler warning as follows:

#pragma warning( disable : 4100 )

4100 is an error code that does not reference parameters. Pragma suppresses the warning of other files/modules. You can use the following method to re-enable this warning:

#pragma warning( default : 4100 )

In any case, it is better to save all the warning States before disabling a specific warning, and then return to the previous configuration after you finish. In this way, you will return to the previous state, which is not necessarily the default state of the compiler.
So you can use the Pragma command to suppress the unreferenced parameter warning of a single function before and after the Code as follows:

#pragma warning( push ) #pragma warning( disable : 4100 )void SomeFunction(...){}#pragma warning( pop )

Of course, this method is not lengthy for parameters not referenced, but it may not be the case for other types of warnings. Library builders use # pragma warning to block warnings so that their code can be cleaned and compiled with/w4. MFC is full of such pragmas commands. There are many other # pragma warning options that I have not discussed in this article. For more information, see related documents.

I have noticed some applications that have special commands in the context menu that appears when you right-click the Minimize button in the taskbar. For example, Winamp (a popular media player) has an additional "Winamp" menu item, which is a Winamp-specific command. How do I add my own menu items in the task bar of the program?

Jirair osygian

I created a simple MFC SDI program that displays a counter in form view. I want to control start/stop the counter by right-clicking the Minimize button of the Program on the taskbar. In the form view, the button-controlled start/stop function runs normally. I can also add the start/stop command to the system menu. However, I did not respond when I clicked the added System menu. How can I handle these custom system menu messages? Monicque Sharman

When you right-click the Minimize button of the application on the taskbar, the menu displayed by the user is the same as that displayed by clicking the application title bar icon in the upper left corner or pressing Alt + space. See figure 1. This menu is called a system menu, including commands such as restore, minimize, maximize, and close.


Figure 1 System Menu

You can call: getsystemmenu to obtain the system menu, and then add, delete, or modify the menu item. You can even disable the ws_sysmenu window style icon or the precreatewindow virtual function to completely block this system menu. However, no matter what you do, the system menu is displayed when you right-click the Minimize button of the application on the taskbar.
Monicque: If you add your own commands to the system menu, how does MFC handle them? If you write an on_command processor somewhere and add it to the Message ing, you will find that your processor does not work. How can this happen?
That's because windows and MFC process system commands in a different way than normal menu commands. When you call a conventional menu command or button in the form, Windows sends a wm_command message to the main window. If you use MFC, its command routing mechanism will capture the message and route it to the on_command command processor object of the command through the operating system. (For details about the MFC command processing mechanism, refer to the article "meandering through the maze of MFC message and command routing" I published in MSJ in July 1995 ").
However, system commands do not belong to the wm_command message range. Another message is called -- wm_syscommand. Whether the command ID is a real system command, such as SC _minimize and SC _close, or other command IDs you have added. To process system menu commands, you must explicitly process wm_syscommand and select your own command IDs. In this case, you need to add on_wm_syscommand to the Message ing in the main window. It has a processing function as follows:

Cmainframe: onsyscommand (uint NID, lparam LP) {If (nid = id_my_command ){... // process it return 0;} // pass it to the base class: This step is very important! Return cframewnd: onsyscommand (NID, LP );}

If this command is not yours, do not forget to pass it to your base class for processing-typically, it is cframewnd or cmdiframewnd. Otherwise, Windows will not be able to get this message and will destroy the built-in command.
It is acceptable to process wm_syscommand in the main framework, but it is too amateur to do so. Why should we use a special mechanism? Is it because they are system menus? What if you want to process system commands in a view or document object? A common command is put in the System menu, which is "about" (id_app_about). Most MFC programs process id_app_about in application objects:

void CMyApp::OnAppAbout(){    static CAboutDialog dlg;    dlg.DoModal(); }

A really cool feature of MFC is its command routing system, which allows non-window objects like cmyapp to process menu commands. Many programmers do not even know how such an exception exists. If you have already processed id_app_about in the Application object, why should you implement a separate mechanism after adding id_app_about to the system menu?
It is better to process the added system commands, or the more MFC method should be to pass them through the conventional command routing mechanism. Then, write the on_command processing routine in the conventional methods of MFC to process system commands. You can even use on_update_command_ui to update your system menu items, such as disabling a menu item or displaying a check mark next to the menu item.
Figure 2 is a Class I wrote, csyscmdrouter, which converts system commands into Common commands. To use this class, you only need to instantiate csyscmdrouter in the main framework and call its init method from oncreate:

Int cmainframe: oncreate (...) {// Add my menu items to the System Menu cmenu * pmenu = getsystemmenu (false); pmenu-> appendmenu (.. id_mycmd1 ..); pmenu-> appendmenu (.. id_mycmd2 ..); // use the MFC route system command m_syscmdhook.init (this); Return 0 ;}

Once you call csyscmdrouter: init, You can process id_mycmd1 and id_mycmd2 in the conventional way, and write on_command processing routines for any objects in the MFC command Routing Mechanism-views, documents, and frameworks, the application or any other command object added by rewriting ondomainmsg. Csyscmdrouter also allows you to use the on_update_command_ui processor to update the System menu. The only thing to note is that the command IDs should not conflict with other menu commands (unless they do represent the same command) or built-in system commands. the built-in system commands start from SC _size = 0xf000. The IDS command specified by Visual Studio. NET starts from 0x8000 = 32768. Therefore, if you want Visual Studio to specify IDs, you only need to set no more than 0xf000-0x8000 = 0x7000. That is, the decimal 28,762. If your application has more than 28000 commands, you need to consult a programming psychiatric expert.
How does csyscmdrouter implement its magic? Simple: it uses the ubiquitous csubclasswnd in my previous column. Csubclasswnd allows you to subclass the MFC window object without having to derive from it. Csyscmdrouter derives from csubclasswnd and uses it to subclass the main framework. In particular, it intercepts the wm_syscommand message sent to the framework. If the command ID belongs to a system command (greater than SC _size = 0xf000), csyscmdrouter transmits the message along the Windows road; otherwise, wm_syscommand is eaten and sent as wm_command again, therefore, MFC calls your on_command processor according to its conventional routing process. Very smart, isn't it?
What about the on_update_command_ui processor? How does csyscmdrouter Process System menu commands? Very simple. Before the Windows display menu, he sends a wm_initmenupopup message to your main window. This is the best time for you to update menu items-enable or disable them, add check mark, and so on. MFC creates a ccmdui object for each menu item and passes it to the corresponding on_update_command_ui processor in your message ing. The MFC function with this parameter is cframewnd: oninitmenupopup, which is like this:

void CFrameWnd::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu){    if (bSysMenu)    return; // don''t support system menu    ...}

When initializing the system menu, MFC does not do anything. Why care? What if you want to set bsysmenu to false, even the system menu? This is exactly what csyscmdrouter does. It intercepts wm_initmenupopup and clears the bsysmenu mark, that is, the hiword of lparam:

if (msg==WM_INITMENUPOPUP) {    lp = LOWORD(lp); // (set HIWORD = 0)}

Now, when MFC obtains wm_initmenupopup, it considers this menu as a regular menu. As long as your command IDs does not conflict with the real system menu, everything runs well. If you rewrite oninitmenupopup, the only thing you lose is that you cannot subscribe from the central menu of the main window. Hey, you don't want anything! By Rewriting cwnd: windowproc, you can always process wm_initmenupopup, or compare hmenus if you want to differentiate. But you do not have to worry about where the command comes from.


Figure 3 taskbar menu

To demonstrate all the practices, I wrote a small test program: tbmenu. As shown in figure 3, when you right-click the Minimize button of tbmenu on the taskbar, the menu is displayed. You can see two additional commands at the bottom of the menu. The cmainframe code of tbmenu is shown in Figure 4. You will know where to add commands in oncreate and process them with on_command and on_update_command_ui processors in the message ing of cmainframe. Tbmenu processes id_app_about in its application class (the code is not listed ). Csyscmdrouter allows the system command to work like other commands.

Speaking of commands, let's look at a small piece of information:

In my column in February January, I asked if anyone knows the origins of CTRL + ALT + DEL. Apparently, several readers know how to use Google, because they sent me the same link: an article in USA Today: "thank this guy for 'control-alt-delete'", I found this article before I asked questions on April 9, January. CTRL + ALT + DEL was discovered by a person named David J. Bradley who worked in IBM.
IBM thinks there should be a way to reset (reset) its new PC without power off. Why do we need to use CTRL + ALT + DEL? Technically, David needs two modifiers. He wants a key combination that no one may accidentally knock in. So he chose
CTRL + ALT is used as the modifier key (less than shift) and delete. This key is located at the other end of the keyboard. Therefore, you need two hands to press CTRL + ALT + DEL, at least in the past.
Today's modern keyboard also has CTRL and ALT keys on the right. The original intention of the restart feature is to design a secret security exit for IBM people, but it has become a secret that is not a secret. Once the developer knows about it, they start to tell the customer to use this feature to solve the machine suspension problem. With the development of history, CTRL + ALT + DEL are affectionately known as "three-finger salute", even in today's windows, it is still vital to call up the task manager, so that you can kill a suspended task or terminate the system (for more information about the security key sequence similar to CTRL + ALT + DEL, see this month's security briefs column ). So what if CTRL + ALT + DEL fails? Why does it fail? Hold it for 5 seconds.
David Bradley was one of the 12 engineers who established an ibm pc. He compiled the rom bios. For more information about David, see David J. Bradley.

Happy programming!

Your questions and comments can be sent to Paul's mailbox: cppqa@microsoft.com
 

 

 

 

Author Profile
  Paul dilasciaHe is a freelance writer, consultant, and Web/UI Designer. He is the author of the writing reusable windows code in C ++ book (Addison-Wesley, 1992. Learn more through http://www.dilascia.com.
This article is from the May 2005 Journal of msdn magazine and can be obtained through a local newsstand, or preferably subscribed




Programs in windows are organized as follows:
When the system starts, it first uses exploer as the first task, which is the first program, and then can be on the desktop (actually a manifestation of Explorer) click Start-run and enter a command to start another program,
The second program will get an hinstance (just like the ID card), and hpreinstance is the explorer ID card

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.