Purpose: Tell the compiler that the variable has been used and no warning is needed!
In the VC compiler, If you compile with the highest level, the compiler will give you a very small warning. When a variable is not used, the compiler reports a warning:
"Warning c4100: ''xxxx'': unreferenced formal parameter ."
Therefore, to prevent the compiler from checking your warning, use the unreferenced_parameter statement. For example:
Int somefunction (INT arg1, int arg2)
{
Unreferenced_parameter (arg2)
...
}
I have seen some C ++CodeUnreferenced_parameter is used 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)
In other words, unreferenced_parameter expands the passed parameter or expression. The purpose is to prevent the compiler from warning about unreferenced parameters. ManyProgramPersonnel, 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 noticed some applicationsWhen you right-click the Minimize button on the taskbar, you can use special commands in the context menu that appears. 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 more information about the MFC command processing mechanism, see Article published by MSJ on September 18, July 1995: " meandering through the maze of MFC message and command routing ").
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 2Is 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 as follows: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 for March . 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 September 10, 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 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 has compiled the rom bios. For more information about David, see David J. Bradley .
Happy programming!