Many C + + enthusiasts have been concerned about the many things in my recent column that have penetrated much of C #. I admit it! My only defense is that since the Microsoft®.net Framework has gained wide acceptance, sending me more and more readers of C # issues, and because C # and C + + are so similar, I have answered a part of their questions. This is not my intention to alienate C + + enthusiasts-God knows, I am one of them! In any case, to focus, the C + + column starting this month will focus more on C + + content, including Managed Extensions and traditional content such as MFC. So come up with your C + + problem! I particularly encourage you to raise questions about managed C + +. What do you experience when you use it?
In your March 2004 column, you implemented the initialization of Cmyopendlg by redefining Wm_user+1. I think in the usual sense you misuse the scope of the Wm_user (it is reserved for all registerclass users), in addition to the error wm_user+1 is already a predefined dialog box message Dm_setdefid. Shouldn't you be using a different value for the news?
You're absolutely right! Wm_user is reserved for all who implement the window class-either you, the friendly Redmondtonians, or the rebel on the Gleepoid planet. Figure 1 shows a breakdown of the official Windows message values, which everyone should review at least once every ten years. Wm_user to 0x7FFF is reserved for private window classes. You can think of this scope as a meaningful private message in a particular form class. For instance, the sb_settexta of the status bar control uses Wm_user+1. Also, as you point out, dialog boxes Dm_getdefid and Dm_setdefid use wm_user+0 and wm_user+1. The use of wm_user+1 in my March 2004 column is in conflict with Dm_getdefid.
Applications that want to define their own messages should use Wm_app. Wm_app is to ensure that the system (wm_create, and so on) or class/specific control messages, such as Dm_getdefid, are not conflicting. The Wm_app for Windows definitions are as follows:
#if (WINVER >= 0x0400)
#define WM_APP 0x8000
As every Windows Geek (Geek) knows, winver 0x0400 refers to Windows 95, Windows 98, and Windows NT. So Wm_app's use is less than 10 years old, which explains why I didn't notice it--before 2005, I should not comment on the next 10-year message range!
But am I really going to use Wm_app for Cmyopendlg? Cmyopendlg between Windows and applications. I write it as an extension so that other programmers can use it in their applications. If a programmer is already using Wm_app and is using Cmyopendlg, is there a conflict? This is unlikely in the case of a file open dialog-but what if I'm writing a custom control, such as a toolbar or a progress bar, and need to define my own message? I can get them to avoid conflicts with basic controls based on Wm_app (but there is a risk of conflict with the application) or I can choose a message number such as: wm_user+400, which goes well beyond the Windows control message range. Unfortunately, there is no right answer. This is a problem that has plagued control and class library designers since Windows was released. There is simply no perfect way to divide the message space and ensure that it never leads to conflict. You have to take decisions based on experience every time. For Cmyopendialog, I will select a message like WM_USER+10, which does not conflict with DM_XXX messages. Using the registration message may be too exaggerated.
When it comes to registering messages, what is the difference between a wm_app range and a registered message range (0XC000-0XFFFF), and when should one be selected instead of the other? If you're just saying to yourself--that is, if you're going to just send a message to your application's window, you can use Wm_app to take a range of values. Registration messages are global messages that are sent to other applications written by other programmers. For example, if you are writing a collaboration-management application that itself can determine a program with similar intent by sending a specific message, you should use the registration message:
UINT WM_SAYHELLO = RegisterWindowMessage(_T("WmSayHello"));
Other collaborative applications can then register with this particular name "Wmsayhello" and get the same value, so they can all communicate with each other. The actual Wm_sayhello value for each Windows session will vary, but in one dialog, all applications registering it will have the same value. Of course, the value will always be within the 0XC000-0XFFFF range. Bad,--msdn® magazine has the smartest reader!
I'm writing an application in Managed C + + and I've come across a question about the amount of string literals. I know I can create a string with _t ("sample string") or S "sample string". I also know that S string literals are more efficient, but it seems that very few people know why it works and where it is efficient. What are the differences between the two types of strings? What is the exact meaning of the managed string literal and why is it better?
The best way to understand the difference between a managed string literal and a common C + + string literal is to use them to write the same Code and examine its compilation results. I wrote a simple managed C + + program, StrLit.cpp, which created some String literal quantities in C + + and. NET style, as shown in the code as Figure 2. Figure 3 and Figure 4 show the Microsoft Intermediate Language (MSIL) code that is disassembled with ILDASM. As you may know many things, the primary difference is that when you use C + + text, the compiler produces a call to the corresponding String constructor:
// String* c2 = new String(_T("This is a TCHAR string"));
ldsflda valuetype $ArrayType$0x11197cc2
newobj instance void [mscorlib]System.String::.ctor(int8*)
I'll explain this lengthy and puzzling text right away, but the basic idea is that the compiler loads the address of the C + + string literal, and then produces a newobj instruction that converts the text address to the string's constructor. In addition, the compiler creates a specialized Array type for unmanaged string literals--This is the strange $ArrayType $0x11197cc2 in the preceding code snippet, and one named? A static instance of a0x1f1e2151.unnamed-global-0, as shown in Figure Figure 3: