Tutorial of the MFC non-Modal Dialog Box tutorial-modeless dialogs with MFC development tool: Vc6, vc7, C ++, windows, MFC, VS, vs. net2002, Dev Abstract: Article Explain some tips and suggestions for non-mode Dialog Box Application of MFC. Source code list: Download project [VC ++. Net]-22 KB Introduction Non-mode dialog box is a beginner who is often confusedProgramMember. Basically, a non-mode dialog box is a dialog box that enables us to interact with other windows, even when the non-mode dialog box is still on the screen. If you remember a few nice little tricks, then programming the non-mode dialog box will be very simple. Create non-mode dialog box A simple method to create a non-mode dialog box is to useCreate () . Use the template resource in the name dialog box and an optionalCwnd * To the parent window. If you do not pass a parent window pointer, the main application window will be treated as the parent window.Create () ReturnsTrue If the call is successful. FromCreate () Return immediately, unlikeDomodal () ,You must never declare your modeless dialog as a local variableWith the range and lifetime of only functional functions, this is declarative. Instead of allocating non-mode dialog boxes. If you do not do this, the non-mode dialog box will be destroyed, and you exit the function so that you can declare it. Another solution is to declare your non-mode dialog box as a heap member object your main framework window or yourCwinapp Derived class. 1. The advantage is that you actually have a non-mode dialog box with control permissions because you have a pointer. The mode is different. Non-mode dialog box, non-mode dialog box needs to haveWs_visible Style setting if you don't want them to see it, create it immediately. Otherwise, you will have clear requirementsShowwindow () AndSw_show . In fact, I suggest you do this, instead of changing the default style in all places. Cmodeless * m_pmodeless =NewCmodeless (This); M_pmodeless->Create (cmodeless: IDD); m_pmodeless->Showwindow (sw_show ); Parent questionThe usual practice is to make the main window of the parent window to your application, which is a typical main frame window. One problem is that this is because the non-mode dialog box will remain in the parent window above. It allows you to interact with the main framework window, maybe it also containsCview View. However, it may be annoying and undesirable to have non-mode dialogs left at the top. The solution is to create a non-mode dialog box as a sub-desktop. UseGetasktopwindow () Get a pointer to the desktop, and pass the representation, because the parent window is not a mode dialog box, in your callCreate () . M_pmodeless->Create (cmodeless: IDD, getasktopwindow ()); Destroy non-mode dialog box Now that we have allocated the memory, we have to delete it, and the non-mode dialog box is destroyed, otherwise we will soon encounter a lot of trouble and Memory leakage, left, right and center. When the dialog box destroys the last message, the processing class we receive isWm_ncdestroy Message. TheOnncdestroy Function is referenced.Postncdestroy . This is exactly what we can do.Delete Our non-mode dialog box. First call investigates the function of the base class so that it can clear itself. VoidCmodeless: postncdestroy () {cdialog: postncdestroy ();Delete This;}
Questions and member objects If the non-mode dialog box is a class of the parent window of a member object, we have a slight problem here. The member variable still holds a pointer reference, but its reference memory has been deleted. There is an alternative to this problem. One way is to send the last user-defined message to the parent window and process it in the parent class. By setting the non-mode dialog box member variableNull . Another method is to useGetparent () Obtain the parent window, if any, and then in its actual parent class. Now we have entered the member variable saving pointer to the non-mode dialog box of the parent class. SetNull . The latter method is to depict later I discussed how to restrict the non-mode dialog box to an instance. The former method is as follows :- VoidCmodeless: postncdestroy () {cdialog: postncdestroy (); getparent ()->Postmessage (wm_modeless_closed,0,0);Delete This;} Lresult cmainframe: onmymethod (wparam, lparam) {m_pmodeless = NULL;Return 0;}
Problem onok () and oncancel () In the modal dialog box, everyone includes the Queen's chef with the OK/cancel button. In my opinion, I think you should do well in many other ways to better understand the public's opinions, so as to avoid OK and cancel a non-mode dialog box. However, if you most want to have their non-mode dialog box for you for some inevitable reason, you will need to schedule more than two function types. Here is my non-mode versionOncancel () Function. As you can see, I just calledDestroywindow () And I am not bothered to call the base class. In fact,Don't call the base class at all. Basic functions will be welcomedEnddialog () This correspondsDomodal () . VoidCmodeless: oncancel () {destroywindow ();} Okay, now my non-mode versionOnok () . I have calledDestroywindow () As, inOncancel () But there are some additionalCode, As you can see. I callUpdatedata Because what is this?Onok () Whether it is in a modal dialog box. If the DDV macro is successfully verified, thenUpdatedata (True) Return to the destroy window. Otherwise, the DDV message box is automatically displayed to the user and the refuse to destroy dialog box. Therefore, we are simulating the behavior. The OK button of the modal dialog box is here. VoidCmodeless: onok (){If(Updatedata (True) {Destroywindow ();}} Pass back data In the modal dialog box, when we can still use data variables,Domodal () Returned because the dialog box object is not destroyed, but only the base dialog box window is destroyed. This is also possible for non-mode dialog boxes. Use the beautiful technique, as shown below. VoidCmodeless: onok (){If(Updatedata (True) {(Cmainframe *) m_parent )->M_x = m_sss; destroywindow ();}}
Here, the data variable of the Value dialog box that I have assignedM_sss To the member variable of the parent class,M_x . Here,M_parent Is a pointer to the parent window. Here you want to know that I get thisM_parent Scroll up to see how I have constructed a non-mode dialog box object. I will refresh your memory in a single row and help you avoid scrolling, saving some energy. Cmodeless * m_pmodeless =NewCmodeless (This); You can see that I have passedThis Direction structure. For me, this is a pointerCframewnd Derived class, in which the Application Wizard is namedCmainframe Me. View me nowCmodeless Class structure. Cmodeless: cmodeless (cwnd * pparent/*= NULL */): Cdialog (cmodeless: IDD, pparent ){//{Afx_data_init (cmodeless)M_sss =0;//} Afx_data_initM_parent = pparent;//This is where I point m_parent to my main frame window}
It makes sense, huh? Non-mode dialog box countLet's say you only have one instance, and the non-mode dialog box will live at the same time. In this case, each time the user starts some actions and results, in the enable this non-mode dialog box, you must check to see if the non-mode dialog box is already in operation. That is to say,M_pmodeless It is a member of the non-mode dialog box and your class. Construct a set of ClassesM_pmodeless ,Null . Now you check every time to see ifM_pmodeless YesNull If this isNull To create a new non-mode dialog box. OtherwiseMessageBox The dialog box is active or used.Setforegroundwindow () Bring the non-mode dialog box to the foreground .. Here is how I create my non-mode dialog box now I want to limit them to only one at the time :- If(M_pmodeless) {m_pmodeless->Setforegroundwindow ();}Else{M_pmodeless =NewCmodeless (This); M_pmodeless->Create (cmodeless: IDD); m_pmodeless->Showwindow (sw_show );} However, when the dialog box is destroyed, we must inform the parent class pointer that it is useless now. What we do is set pointerNull , InPostncdestroy . In fact, this is very important. If you do this, otherwise your program will crash when the next user tries to start a non-mode dialog box because it thinksM_pmodeless Still pointing to a valid dialog box window and trying to callSetforegroundwindow () It. Here is mePostncdestroy :- VoidCmodeless: postncdestroy () {cdialog: postncdestroy (); (cmainframe *) m_parent )->M_pmodeless = NULL;Delete This;} |