Simple VC Basic Tutorial

xiaoxiao2021-03-06  43

VC basic tutorial

Preface and Copyright Description 1999/09/05 I reserve the copyright of all articles of this column, and have not been reproduced any institution or individuals without any institutions or individuals. If you need to reprint, please contact the author Wonder.

First of all, I would like to thank the online friends to encourage and support, this is the main driving force for my tutorial prepared, and the gradual column is also the need for the site development itself. In the later time, I will write a tutorial for your reference. I hope that friends who begin to learn VC can get help and guidance. Friends who are familiar with VC can get inspiration, and friends who are proficient in VC can enlighten, and I hope to have a ripping jade. .

In this column, I tell VC development methods and techniques in a step-by-step manner, entry from VC to various forms, dialogue, document view structure, and network development and other advanced topics.

The content of this column: I will tell some of the more important content I think that I think the development of learning is also there. My purpose is to help everyone learn more to learn VC, not big and full explanation VC. How to use, development methods. So I hope that you can have a reference book around you and don't use this column as a reference book you get started. I do this because my time and energy are limited, and there is no scanner and OCR software, it is impossible to write long masterpieces. At the same time, the reference book on the market is not good. I hope to see this column after reading a refined reference book. It can have a feeling of realizing it. (Seem to be a bit exaggerated)

This column object: The tutorial here is mainly written for primary users developed by VC and the newly entitled developers. At the same time, the reader is also required to have a C / C language basis.

Thanks to someone around me, because of their concern and help this column can be adventive. Thanks to my mother gave me a lot of care for many years; my younger brother Zhang Li often gives me some fun games to let me relax myself; our university's mentor Xujia has given me a good experimental environment; My good friend Zhou Jiang often gave me some fresh inspiration; my friend is also a work of my colleague Chen Wei gave me help and guidance; computer newspaper's Hai 13 Contact me this column in the computer Reprinted by the newspaper; there are also those online letters encourage my friends, and they have their own efforts.

If you have any comments or suggestions, please leave a message or contact Wenyi.

Copyright has Wenyi http://www.vchelp.net/ directory - Chapter 1 VC Getting Started package download | ------ 1. How to learn VC | ------ 1.2 Understand Windows Message Mechanism | ----- 1.3 Using Visual C / MFC to develop Windows program advantages | ------ 1.4 Universal Methods Developed with MFC | ------ 1.5 MFC Temperature class, macro, function introduction - Chapter 2 Graphic Output Package Download | ------ 2.1 and GUI related to various objects | ------ 2.2 Output text in the window | ------ 2.3 Use points, brush , Pen drawing | ------ 2.4 Drawing device related bitmap, icon, device in the window | ------ 2.5 Use various mapping methods | ------ 2.6 polygons and Clipping area - Chapter 3 Document View Structure package download | ------ 3.1 Document View Frame Window Inter-Message Transfer Law | ------ 3.2 Receive User Enter | ------ 3.3 Using Menu | ------ 3.4 Document, View, Framework Interaction | ------ 3.5 Using Serialized Document Read / Writing | ------- 3.6 MFC Seiki - Chapter 4 Window Control Package Download | ------ 4.1 Button | ------ 4.2 static box | ------ 4.4 Edit Box | ------ 4.4 Scroll Bar | ------ 4.5 List Box / Check List Box | ------ 4.6 Combo Box / Combo Box EX | ------ 4.7 Tree Ctrl | ------ 4.8 List Ctrl | ------ 4.9 Tab Ctrl | ------ 4.A Tool Bar | ------ 4.B Status Bar | ------ 4.c Dialog Bar | --- 4.D Use AppWizard to create and use Toolbar Statusbar Dialog Bar | ------ 4.F About WM_NOTIFY How to use WM_Notify - Chapter 5 dialog Package download | ------ 5.1 Use the Resource Editor Editing dialog | ------ 5.2 Create a mode dialog box | ------ 5.3 Create a Mode dialog box | ------ 5.4 Perform message mapping in the dialog | ------ 5.5 Data exchange and data check in the dialog | ------ 5.6 Using Properties dialog box | ------ 5.7 Using General Dialog | ------ 5.8 Establishing Application Based on dialog box | ------ 5.9 Use dialog as sub-window - Chapter 6 Network Communication Development Package | ------ 6.1 Winsock Introduction | ------ 6.2 Using Winsock for unconnected communication | ------ 6.3 Using Winsock to establish a connectionful communication - Download the full tutorial completed at 1999/12/07 after three months of patchwork I finally completed this basic tutorial, saying that I didn't expect three months like this, and I might be sacrificed to exchange speed. I will improve the chapters in this tutorial in the future, and I hope everyone will provide more opinions on existing content. Next I may write some advanced tutorials for Visual C / MFC. Thanks again to all friends mentioned earlier.

1.1 How to learn VC

Many friends have asked me, of course, sweat is required, but at the same time, if they have planned learning in accordance with some kind of ideas, they will play a better effect. It's hard to help friends master VC development in order to help friends, let me talk about myself:

1, there is a need for a good C / C foundation. The so-called "knife is not misunderstanding", do not rush to start the Windows program development when contacting VC, but should be written in some character interface programs. The purpose of this is mainly familiar to the language, and it is also training your thinking and familiar with some errors in programming. More importantly, understanding and can use C , which will have a lot of help in future development, especially those who develop by MFC to be able to be skilled in C . 2. Understand the meaning and use of Windows message mechanisms, window handles and other GUI handles. Understand the API function similar to the MFC's class features.

3. Be sure to understand the role of message mapping in MFC.

4, training yourself without using the reference book when writing code, but use Help Online.

5, remember some common message names and parameters.

6, learn to see someone else's code.

7, read more books, less bought books, must be cautious before buying books.

8. Look at the reference book when you are idle.

9, come to my homepage. ^ O ^

There are several comments in my personal, you can choose the method for your own as needed and your own situation.

In addition, I will some of the principles I am using the reference book:

For beginners: There should be some comprehensive books, and the contents of books should be arranged in a reasonable way. When using the book, you can reach a step-by-step effect, and the code in the book has a detailed explanation. Try to buy translation books, because these books are generally more easy to understand, and language is relatively easy. Before buying a book, you must carefully if you buy a bad book may have a blow to your learning enthusiasm.

For friends who have already mastered VC: This level of developers should deepen their understanding of system principles, technical points. It is necessary to choose some relatively thorough books to the principle, so that there will be more understanding of new technologies, and the best books have certain elaborations in the application. Try to choose a book that the demonstration code will be more streamlined, save money.

In addition, it is best to hunt about some auxiliary books.

Copyright 怡 洋 http://www.vchelp.net/

1.2 Understanding the Windows Message Mechanism

The Windows system is a message-driven OS, what is the message? I am hard to say clearly, it is also difficult to define (who is I), I will explain from different aspects, I hope everyone will understand.

1, the composition of the message: A message consists of a message name (UINT), and two parameters (WPARAM, LPARAM). The system will send a message to a window when the user has changed or the state of the window changes. For example, there will be a WM_COMMAND message sent after the menu is transferred, and the HiWord (WPARAM) is the ID number of the command, and the menu is the menu ID. Of course, users can define their own message names, or use custom messages to send notifications and transfer data.

2, who will receive a message: A message must be received by a window. The message can be analyzed in the process (WndProc) to process the messages of yourself. For example, you want to handle the menu selection Then you can define the code that processes the WM_COMMAND. If you want to perform graphic output in the window, you must process WM_PAINT.

3, the unopened message is there: M $ writes the default window process for the window, which will be responsible for handling those you do not address messages. Because of this default window process, we can use Windows window to develop without having to pay too much attention to the processing of various messages. For example, there will be a lot of messages sent when the window is dragged, and we can use it to handle the system yourself.

4, window handle: When you say messages, you cannot say a window handle. The system is uniquely identified in the entire system through the window handle. When you send a message, you must specify a window handle indicating that the message is received by that window. Each window will have its own window process, so the user's input will be processed correctly. For example, there are two windows sharing a window process code, and when you press the mouse on the window, the message will be sent to the window until the window is not the window. 5. Example: There is a pseudo code to demonstrate how to process messages during the window.

Long YourWndProc (HWND HWND, UINT UMESSAGETYPE, WPARAM WP, LPARAM) {Switch (UMESSAGETYPE) {// Use switch statement to separate Case (WM_Paint): DoyourWindow (...); // When the window needs to re-draw Output Break; Case (WM_LBUTTONDOWN): DoyourWork (...); // During the mouse button is pressed and processed; default: CallDefaultWndProc (...); // For other cases, let the system handles Break }}

Let's talk about what is a message mechanism: The system will maintain one or more message queues, all generated messages are placed back or inserted into the queue. Each message will be taken in the queue, and the message is sent to the message loop of the program with the window according to the message receiving handle. Each running program has its own message loop, gets its own message in the loop and calls the corresponding window process based on the handle of the received window. When there is no message, the message loop will give the control to the system so Windows can simultaneously perform multiple tasks. The following pseudo code demonstrates the usage of the message loop:

While (1) {id = getMessage (...); if (id == quit) Break; translateMessage (...);}

When the program does not have a message notification, GetMessage will not return, and it will not take up the system's CPU time. Illustration message delivery mode

There is only one message queue in the system in the 16-bit system, so the system must wait for the current task to process the message to send the next message to the corresponding program. If a program is trapped, the system will not be To control. This multitasking system is also called a multi-tasking system. Windows3.x is this system.

Each running program in the 32-bit system will have a message queue, so the system can be converted in multiple message queues without waiting for the current program to complete message processing. This multi-tasking system is called a predetermined multitasking system. Windows95 / NT is this system.

Copyright 怡 洋 http://www.vchelp.net/

1.3 Using Visual C / MFC to develop a Windows program advantage

The MFC has opened up a new world with the development of C , and also with ApplicationWizzard, which makes developers from the basic code. With the ClassWizard and message mapping, the developers get rid of the confusion when the developers get rid of defined messages. The lengthy code segment. More exciting is to use C packages to enable developers to get rid of various handles in Windows, only need to face objects in C , so that the development is closer to the development language and far from the system. (But I personally think that understanding the system principle is very helpful for development)

Because the MFC is based on C , I emphasize the importance of the C / C language foundation for development. Using C encapsulatory developers can more easily understand and operate various window objects; use C derived developers to reduce the time and reusable code for developing custom windows; use virtuality can be better when necessary The activity of the control window. And the characteristics of the transcendent C itself can make developers to write more easily, more flexible code. The processing of the message in the MFC utilizes a message mapping method. The basis of this method is the macro definition implementation, assisted the message to a different member function by macro definition. The following is simple to tell the implementation method of this method:

Code is as follows BEGIN_MESSAGE_MAP (CMainFrame, CFrameWnd) // {{AFX_MSG_MAP (CMainFrame) ON_WM_CREATE () //}} AFX_MSG_MAP ON_COMMAND (ID_FONT_DROPDOWN, DoNothing) END_MESSAGE_MAP () after compilation, the code is replaced with the following form (as it was just explained, the actual The situation is much more complicated than this): // begin_MESSAGE_MAP (CMAINFRAME, CFRAMEWND) CMAINFRAME :: NewWndProc (...) {switch (...) {// {{AFX_MSG_MAP () // ON_WM_CREATE () Case (wm_create) : Oncreate (...); break; //}} AFX_MSG_MAP // ON_COMMAND (ID_FONT_DROPDOWN, DONOTHING) CASE (WM_COMMAND): IF (HiWord (WP) == id_font_dropdown {donothing (...);} Break; / / END_MESSAGE_MAP ()}

NewWndProc is the window process as long as the window generated by this class is used.

So understanding the Message Mechanism of Windows is easy to understand the basic ideas of MFC development in addition to the understanding of the message mapping.

Copyright 怡 洋 http://www.vchelp.net/

1.4 General Method for Developing MFC

The following is the development ideas and methods I have used in the initial study of VC, I hope to help and inspire friends from beginner VC.

1. Develop applications that need to read and write files and have simple inputs and outputs to utilize a single text file structure.

2. Develop a simple application that focuses on interaction, you can use the dialog-based window, if the file read and write is simple, you can use the CFile.

3. Develop a simple application that focuses on interaction and document reading and writing, which can use the single text file structure that is based on CFormView.

4. Use the dialog to get the data entered by the user, and can be entered after the level is increased.

5. When the multi-document is required to avoid a multi-document structure, the multi-document structure can be used to generate a single document multiplexed structure.

6. A multi-document structure is used when data is required to pass data between multiple documents.

7. Learn to use the sub-window and contain multiple controls to achieve the purpose of the encapsulation function in the custom sub-window.

8. Try to avoid multi-purpose multi-view structure.

9. Do not use multiple inheritance and try to reduce the function of excessive packaging in a class.

Copyright 怡 洋 http://www.vchelp.net/

1.5 MFC often use, macro, function introduction

Common class

CRECT: The class used to represent a rectangle, with four member variables: Top Left Bottom Right. The table is the coordinate of the upper left corner and the lower right corner. Can be constructed by the following method:

CRECT (int L, int T, int R, int b); specified four coordinates

CRECT (Const Rect & SrcRect); constructed by RECT structure

CRECT (LPCRect LPSRCRECT); constructed CRECT (Point Point, Size Size) by the Rect structure; there is a coordinate and size construct in the upper left corner

CRECT (Point Topleft, Point Bottomright); Two Coordinate Construction

Let's introduce a few member functions:

Int width () const; gets a width INT height () Const; gets a high degree cpoint & toplex (); get the upper left corner coordinate cpoint & bottomright (); get the lower right corner CPoint centerpoint () const; Coordinates Further rectangles can be added to the point (CPOINT), and the rectangle after the other rectangle is added "and" operation.

Cpoint: It is used to represent a coordinate of a point, there are two member variables: x y. Can be added to another point.

CSTRING: The string used to represent a variable length. Using CString does not specify the memory size, CString will allocate themselves as needed. Let's introduce a few member functions:

GetLength gets the string length getat gets the character Operator equivalent to STRCAT VOID FORMAT (LPCTSTR LPSZFORMAT, ...); equivalent to Sprintf Find Find Specified Characters, String Compare Comparison Comparenocase Indescale Size Comparison Makeupper change to lowercase Makelower changed to uppercase

CSTRINGARRAY: The array of strings used to represent variable lengths. An instance of each element in an array is a CString object. Let's introduce a few member functions:

Add Add CSTRING Removeat Delete Specified Location CString Object RemoveAll Delete All CString Object Getat Get Cstring Object Sett Modified CSTRING Objects in Specified Location Inserts in a certain location CSTRING object

Common macro

RGB

Trace

Assert

Verify

Common function

CWindApp * AFXGETAPP ();

Hinstance afxgetinstancehandle ();

Hinstance AfxgetResourceHandle ();

INT AFXMessageBox (LPCTSTR LPSZTEXT, UINT NTYPE = MB_OK, UINT NIDHELP = 0); used to pop up a message box

Copyright 怡 洋 http://www.vchelp.net/

2.1 and GUI related objects

There are various GUI objects (not confused with C objects) in Windows, when you are drawing, you need to use these objects. The various objects have various properties, and the following describes the various GUI objects and their properties.

Font Objects CFont uses different styles and size fonts when the text is output. The selectable style includes: whether it is a slope, whether it is a bold, the font name, whether it is underscore, etc. Colors and background colors are not in the font properties. Regarding how to create and use fonts in 2.2, you will explain in detail in the output text in the window.

The brush CBRUSH object determines the color or template used in the fill area. For a fixed color brush, its attribute is color, whether the type of grid and grid is used, vertical, cross-like, etc. You can also create a custom template with a bitmap of 8 * 8, and the system will use the bitmap to step by step by step by using this brush. Regarding how to create and use a brush to use a brush in 2.3, the pen will explain in detail.

The brush CPEN object is useful when drawing points and lines. Its properties include color, width, line style, such as dashed lines, solid lines, dotlines, etc. About how to create and use a brush to use a brush in 2.3, the pen will explain in detail. Bitmap CBITMAP objects can contain an image that can be saved in the resource. About how to use bitmaps in 2.4 Drawing device-related bitmaps, icons, and device-free bitmaps in the window.

There is also a special GUI object is a polygon, which can limit the map area or change the window exterior using a polygon. About how to create and use polygons explain in detail in a 2.6 polygon and scrapbooking area.

Use the GUI object in Windows to comply with certain rules. First, you need to create a legitimate object, and different object creation methods are different. The GUI object is then required to select the DC while saving the original GUI object in the DC. If an illegal object is selected will cause an exception. After use, the original object should be restored. This is especially important. If a temporary object is saved in the DC, it may cause an exception after the temporary object is destroyed. One must pay attention to that every object must be destroyed before recreation, the following code demonstrates this safe usage:

OnDraw (CDC * PDC) {CPEN PEN1, PEN2; Pen1.createpen (PS_SOLID, 2, RGB (128, 128, 128)); // Create object pen2.createpen (PS_SOLID, 2, RGB (128, 128, 0)); // Create an object CPEN * PPENOLD = (CPEN *) PDC-> SelectObject (& Pen1); // Select Object into DC DrawWithpen1 ... (CPEN *) PDC-> SelectObject (& Pen2); // Select Object into DC DrawWithpen2 ... Pen1. DeleteObject (); //, first destroy Pen1.createpen before you create; // Create an object again (CPEN *) PDC-> SelectObject (& Pen1) again; // Select object Enter DC DrawWithpen1 ... PDC-> SelectObject (POLDPEN); // Restore}

In addition, there are some stock GUI objects, you can use CDC :: SelectStockObject (SelectStockObject (INT NINDEX) to select these objects, including some fixed color brushes, brushes, and some basic fonts.

Black_brush black brush.

Dkgray_brush dark gray brush.

Gray_brush gray brush.

Hollow_brush hollow brush.

LTGRAY_BRUSH LIGHT GRAY Brush.

NULL_BRUSH NULL BRUSH.

White_brush white brush.

Black_pen black pen.

NULL_PEN NULL PEN.

WHITE_PEN WHITE PEN.

ANSI_FIXED_FONT ANSI FIXED SYSTEM FONT.

ANSI_VAR_FONT ANSI VARIABLE SYSTEM FONT.

Device_Default_font device-dependent font.

OEM_FIXED_FONT OEM-Dependent Fixed Font.

.. SYSTEM_FONT The system font By default, Windows uses the system font to draw menus, dialog-box controls, and other text In Windows versions 3.0 and later, the system font is proportional width; earlier versions of Windows use a fixed-width system Font.system_fixed_font the fixed-width system font used in Windows prior to version 3.0. This Object is Available for Compatibility with Earlier Versions Of Windows.

These objects are safe in the DC, so you can use the inventory object as a GUI object in the restoration DC using the inventory object.

Everyone may have noticed that a DC object is required, and the DC (Device Context Device Environment) object is an abstract mapping environment, which may be a corresponding screen or other printer or others. This environment is independent of equipment, so you only need to use different device environments when you output different devices, and mapping can be completely unchanged. This is also unrelated to the dazzling device of Windows. Like you will use a camera or a copying machine to generate different outputs without any adjustment of painting. The use of DC will be inserted in this chapter.

Copyright 怡 洋 http://www.vchelp.net/

2.2 Output text in the window

Here I assume that the reader has generated a program code for an SDI interface with ApplicationWizard. Next you only need to join the drawing code in the CVIEW derived Ondraw member function. Here I need to explain the role of the onDraw function, the onDraw function is automatically called when the window needs to be redrawged, and the incoming parameter CDC * PDC corresponds to the DC environment. The advantage of using OnDRAW is that the DC environment that is incoming to the OnDraw when you use the print function, it will be a printer drawing environment. When you use a print preview, it is incoming a drawing environment called CPREVIEWDC, so you only need a code. You can complete window / print preview / printer drawing triple function. Using Windows Devices Non-related and M $ to print preview, you can easily complete a software with what you get.

Output text generally uses CDC :: Bool Textout (int X, int y, const cstring & str), and CDC :: Int Drawtext (Const Cstring & Str, LPRect LPRect, Uint Nformat), only to output a single line for Textout Text, while DrawText can specify whether to output a single line or multi-line text in a rectangle, and can specify alignment and what style of use. NFORMAT can be a combination of a plurality of markers (use bits or operations) to achieve the purpose of selecting output styles.

DT_BOTTOM bottom aligned specifies bottom-justified text. This value must be combined with dt_singeline.

DT_CALCRECT The rectangular dimensions Determines the width and height required of the rectangle. If there are multiple lines of text, DrawText will use the width of the rectangle pointed to by lpRect and extend the base of the rectangle to bound the last line when calculating the specified text of text. If there is only one line of text, DrawText will modify the right side of the rectangle so that it bounds the last character in the line. in either case, DrawText returns the height of the formatted text, but does not draw the TEXT.DT_CENTER Central Align Centers Text Horizontally.

DT_END_ELLIPSIS or DT_PATH_ELLIPSIS Replaces part of the given string with ellipses, if necessary, so that the result fits in the specified rectangle. The given string is not modified unless the DT_MODIFYSTRING flag is specified. You can specify DT_END_ELLIPSIS to replace characters at the end of the string, or DT_PATH_ELLIPSIS to replace characters in the middle of the string. If the string contains backslash (/) characters, DT_PATH_ELLIPSIS preserves as much as possible of the text after the last backslash.

DT_EXPANDTABS Expands Tab Characters. The Default Number of Characters Per Tab Is Eight.

.

DT_LEFT left aligned Aligns text flush-left.

DT_MODIFYSTRING Modifies the given string to match the displayed text. This flag has no effect unless the DT_END_ELLIPSIS or DT_PATH_ELLIPSIS flag is specified. Note Some uFormat flag combinations can cause the passed string to be modified. Using DT_MODIFYSTRING with either DT_END_ELLIPSIS or DT_PATH_ELLIPSIS may cause the string To be modified, causing an assertion in the cstring override.

DT_NOCLIP Draws without clipping. DrawText is somewhat faster when DT_NOCLIP is used.DT_NOPREFIX prohibit the use of the prefix & Turns off processing of prefix characters. Normally, DrawText interprets the ampersand (&) mnemonic-prefix character as a directive to underscore the character that follows, and The Two-ampersand (&&) MNemonic-Prefix Characters As a Directive to Print A Single Ampersand. by Specifying DT_noprefix, this processing is turned.

DT_PATH_ELLIPSIS

DT_Right Right Align Aligns TEXT FLUSH-RIGHT.

DT_SINGLINE Single Line Output Specifies Single Line Only. Carriage Returns and Linefeeds Do Not Break The Line.

DT_TABSTOP Sets the width set of Tab characters Sets Tab Stops. The high-order byte of nformat is the number of character byte of nformat is the demult number of characters per tab is elete.

DT_TOP Division Aligns Specifie Top-Justified Text (Single Line Only).

DT_VCENTER Central Align Specifies Vertically Centered Text (Single Line Only).

DT_WORDBREAK per line is wrapped Specifies word-breaking between words. Lines are automatically broken between words if a word would extend past the edge of the rectangle specified by lpRect. A carriage return Zhe inefeed sequence will also break the line.

If you want to change the color of the text when you output text, you can use CDC :: SetTextColor (ColorRef CRColor), if you want to change the background color, use CDC :: SetBkcolor (ColorRef Crcolor), you may need a transparent background. You can use CDC :: setBkmode (int NBKMODE) to set up, acceptable parameters

OPAQUE Background Is Filled with The Current Background Color Before The Text, Hatch. This Is The Default Background Mode.

Transparent background is not change before drawing.

Next, how to create fonts, you can create two types: stock fonts CDC :: CreateStockObject (int NINDEX) and custom fonts. You need to populate a logfont structure when you create a non-stock font and use cfont :: createFontIndirect (Const Logfont * LPLogfont) (you can refer to the article to display GB characters and BIG5 characters in the same system), or use cfont :: CreateFont (int NHEIGHT, INT) nWidth, int nEscapement, int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline, BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision, BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily, LPCTSTR lpszFacename) parameters and LOGFONT wherein the component to be correspond relationship. The meaning of the parameters is explained below: NHEIGHT font height (logical unit) is equal to zero to default height, otherwise absolute value and can match the font height. NWIDTH width (logical unit) If zero is used to match the available horizontal bow. The angle of the font angle between the baseline and the X-axis between the nEscapement outlet vector X axis nOrientation nWeight font weight, take the values ​​Constant Value FW_DONTCARE 0 FW_THIN 100 FW_EXTRALIGHT 200 FW_ULTRALIGHT 200 FW_LIGHT 300 FW_NORMAL 400 FW_REGULAR 400 FW_MEDIUM 500 FW_SEMIBOLD 600 FW_DEMIBOLD 600 FW_BOLD 700 FW_EXTRABOLD 800 FW_ULTRABOLD 800 FW_BLACK 900 FW_HEAVY 900

BITALIC is a slope Bunderline whether there is a downline CSTRIKEOUT whether it takes a delete line ncharset specifies a character set, and the following value can be obtained constant value ansi_charset 0 Default_charset 1 symbol_charset 2 Shiftjis_Charset 128 OEM_CHARSET 255

NOUTPRECISION output accuracy OUT_CHARACTER_PRECIS OUT_STRING_PRECIS OUT_DEFAULT_PRECIS OUT_STROKE_PRECIS OUT_DEVICE_PRECIS OUT_TT_PRECIS OUT_RASTER_PRECIS

NclipPrecision clipping accuracy, can be obtained by clip_character_precis clip_mask clip_default_precis clip_stroke_precis clip_encapsulate clip_tt_always clip_lh_angles

NQuality output quality, you can take the following value

DEFAULT_QUALITY APPEARANCE OF THE FONT DOES NOT MATTER.

Draft_quality apparance of the font is lessportant Than When Proof_quality is buy, scaling is enabled. Bold, italic, underline, and strikeout fonts are synthesized if nesery.

PROOF_QUALITY Character quality of the font is more important than exact matching of the logical-font attributes. For GDI raster fonts, scaling is disabled and the font closest in size is chosen. Bold, italic, underline, and strikeout fonts are synthesized if necessary. The spacing of the NpitchandFamily font between the NPITCHANDFAMILY fonts Specifies the font name, in order to get the font owned by the system, EmunfontFamiliex can be utilized. (You can refer to the article to display GB characters and BIG5 characters in the same system) In addition, CFontDialog can be utilized to get the logFont data of the font selected by the user.

Finally, I talked about the calculation of the text coordinates, using CDC :: GetTextExtent (Const CString & Str) to get the width and height of the string when the output is output, so that the correct line spacing can be used when manually output multi-line characters. In addition, if you need more precisely, you need to use CDC :: GetTextMetrics (LPTextMetric LPMETRICS). This function will populate the TEXTMETRIC structure, which can be very accurately descriptated by various properties of the font.

Copyright 怡 洋 http://www.vchelp.net/

2.3 Use points, brush, pen to draw

The method of painting in Windows is simple, just call ColorRef CDC :: SetPixel (int X, int y, colorRef crcolor) to specify the color on the specified point while returning the original color. ColorRef CDC :: getPixel (int x, int y) can get the color of the specified point. There should be fewer functions of the drawpoints in Windows, as the execution efficiency is relatively low.

The brush and brush are using the most GUI objects in the Windows Multi-Draw, which in this section explains the brush and brush how to use the basic mapping function.

The system uses the brush in the current DC when drawing points or line, so it must produce the DC when the brush is created. The brush can be generated by CPEN objects, created by calling CPEN :: Createpen (int NPENSTYLE, INT NWIDTH, ColorRef crColor). Where nPenStyle names the style of the brush, you can take the following value:

PS_SOLID Line Creates A Solid Pen.

Ps_dash dashed line, width must be a Creates a dashed pen. Valid Only when the pen width is 1 or LESS, IN Device Units.

PS_DOT Point, the width must be a Creates a dotted pen. Valid Only when The Pen Width IS 1 or Less, in Device Units.

Ps_dashdot dotted, width must be a Creates a pen with alternating dashes and dots. Valid ONLY WHEN THE PEN WIDTH IS 1 or LESS, in Device Units.

Ps_dashdotdot Double Distirement, Width Must for a Creates A Pen With Alternating Dashes and Double Dots. Valid Only When the Pen Width IS 1 or LESS, IN Device Units.ps_null Airline, what does not produce what Creates a null Pen .

The PS_ENDCAP_ROUND end is rounded End Caps Are Round.

Ps_ENDCAP_SQUARE End is square End Caps Are Square.

NWIDTH and CRCOLOR are width and colors of the line.

The brush is used to fill the color when drawing the closure curve, for example, when you draw circular or square, the system will be filled inside with the current brush. The brush can be produced using the CBRUSH object. Create a brush through the following functions:

BOOL CreateSolidBrush (COLORREF crColor); the creation of a solid color brush BOOL CreateHatchBrush (int nIndex, COLORREF crColor); and create the specified color mesh brush, nIndex take the values: HS_BDIAGONAL Downward hatch (left to right) at 45 degrees

HS_CROSS HORIZONTAL AND VERTICAL CROSSHATCH

HS_Diagcross Crosshatch at 45 Degrees

HS_FDIAGONAL UPWARD HATCH (Left to Right) AT 45 DegRees

HS_HORIZONTAL HORZONTAL HATCH

HS_Vertical Vertical Hatch Bool CreatePatternbrush (cbitmap * pbitmap); Create a brush with 8 * 8 bitmap template

After selecting the brush and the brush, you can use Windows's mapping function to make a map, the basic line function has the following

CDC :: MoveTo (int x, int y); change the location of the current point CDC :: Lineto (int x, int y); draw a line CDC :: Bool Arc (lpcRect LPRECT, POINT) by the current point to parameter PTSTART, POINT PTEND; Pandem CDC :: Bool Polyline (LPPOINT LPPOINTS, INT NCOUNT); Basic Multi-line Supper Connection Basic Multi-Crame Functions The following: CDC :: BOOL Rectangle (LPCRect LPRECT); Rectangle CDC :: RoundRect (LPCRECT lpRect, POINT point); rounded rectangle CDC :: draw3dRect (int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight); 3D frame CDC :: Chord (LPCRECT lpRect, POINT PTStart, Point Ptended; fan-shaped CDC :: Ellipse (LPCRect LPRECT); Elliptical CDC :: Pie (LPCRect LPRECT, POINT PTSTART, POINT PTEND); CDC :: Polygon (LPPOINT LPPOINTS, INT NCOUNT); polygon for rectangular, round Shape or similar enclosures, the system uses a brush to draw the edge and use the brush to fill the interior. If you don't want to fill or draw edges, you can choose empty brush (null_pen) or (null_brush) empty.

The following code creates a solid line with two pixel wide and selects DC. And simple mapping: {... cpen pen; pen.createpen (ps_solid, 2, rgb (128, 128, 128)); cpen * Poldpen = (CPEN *) Dc.selectObject (& Pen); dc.selectstockObject (null_brush); // Select empty brush dc.Rectangle (CRECT (0, 0, 20, 20)); // Painting Rormforms ...} Copyright All Wenyi http://www.vchelp.net/

2.4 Drawing equipment related bitmaps, icons, and equipment in the window

In Windows, you can copy a pre-prepared image to the display area, which is very fast. Two ways to use graphic copy are available in Windows: The device-related bitmap (DDB) and the device are unlocked (DIB).

DDB can be represented by cbitmap in the MFC, and DDB is typically stored in a resource file. When loading, you only need to load graphics by the resource ID number. Bool cBitmap :: loadBitMap (Uint NidResource) can be loaded into the specified DDB, but must be performed with the other and the current drawing DC compatible memory DC. Graphics are drawn by cdc :: bitblt (int X, int y, int NWidth, int NHEIGHT, CDC * Psrcdc, INT XSRC, INT YSRC, DWORD DWROP), and specify the type of grating operation. Bitblt can copy the source DC mediated into the DC, where the first four parameters are the coordinates of the destination area, which is next to the source DC pointer, then the start coordinate in the source DC, because Bitblt is equivalent to copy, so You don't need to specify a long width again, and the StretchBLT can be scaled) The last parameter is the type of grating operation, and the following values ​​are available:

The Blackness output area is a black Turns All Output Black.

Dstinvert Inverse Output Area Inverts The Destination Bitmap.

MergeCopy Using and Operation between Source and Destination Combines The Pattern and The Source Bitmap Using The Boolean and Operator.

MergePaint uses OR OR OR OR Operation Combines The Inverted Source Bitmap with The Destination Bitmap Using The Boolean Or Operator.

Notsrccopy copies the back of the back to the destination Copies the inverted source bitmap to the dateination.

Patinvert Source and Destination XOR Operation Combines The Destination Bitmap with The Pattern Using The Boolean XOR Operator.

Srcand Source and Destination and Operation Combines Pixels of The Destination and Source Bitmaps Using The Boolean and Operator.

Srccopy Replication Source to the destination area COPIES The Source Bitmap to The Destination Bitmap.

SRCINVERT Source and Destination XOR Operation Combines Pixels of The Destination and Source Bitmaps Using The Boolean XOR Operator.

SrcPainT Source and Destination OR Operation Combines Pixels of The Destination and Source Bitmaps Using The Boolean or Or Operator.Whiteness Output Area is White Turns All Output White. The following is demonstrated with this method: CYOOOVIEW :: OnDRAW (CDC * PDC) { CDC memDC; // define a compatible DC memDC.CreateCompatibleDC (pDC); // Create DC CBitmap bmpDraw; bmpDraw.LoadBitmap (ID_BMP); // charged DDB CBitmap * pbmpOld = memDC.SelectObject (& bmpDraw); // save the original There is DDB, and is selected to enter DDB into DC PDC-> Bitblt (0, 0, 20, 20, & MEMDC, 0, 0, Srcopy); // Copy the source DC (0, 0, 20, 20) to the purpose DC (0, 0, 20, 20) PDC-> Bitblt (20, 20, 40, 40, & MEMDC, 0, 0, Srcand); // Put the source DC (0, 0, 20, 20) and destination DC The area in (20, 20, 40, 40) is AND operation MEMDC.SELECTOBJECT (PBMPOLD); // Select the original DDB}

(Icon is not a GDI object, so you don't need to select DC) There is no special icon class in the MFC, because the operation is relatively simple, using Hicon CWINAPP :: Loadicon (uint nidresource) or Hicon CWinapp :: LoadStandardon ( LPCTSTR LPSZICONNAME) After loading, you can use BOOL CDC :: Drawicon (INT X, INT Y, HICON HICON). Since the transparent area can be specified in the icon, the use of icons will be relatively simple when some non-rule graphics need to use a non-rule, and the area is not large. The simple code is given below:

OnDraw (CDC * PDC) {Hicon Hicon1 = AFXGETAPP () -> Loadicon (IDi_i1); Hicon Hicon2 = AFXGetApp () -> Loadicon (Idi_i2); PDC-> Drawicon (0, Hicon1); PDC-> Drawicon 0, 40, Hicon2); Destroyicon (Hicon1); Destroyicon (Hicon2);

Similarly, the MFC has not provided a class class, so we need to read the header information in the bitmap file when using the DIB bitmap, and read the data, and use the API function StretchDibits to draw. The bitmap file starts with the BitmapFileHeader structure, and then the BitmapInfoHeader structure and the color palette information and data. In fact, bitmap format is the simplest in graphics format, and is also one of Windows. I don't detail the structure of the DIB bitmap, provide a CDIB class for everyone to use, this class contains basic functions such as: Load, Save, DRAW. Download CDIB 4K

Copyright 怡 洋 http://www.vchelp.net/

2.5 Use various mapping methods

The so-called mapping method is simple to talk about the arrangement of coordinates. The default mapping mode of the system is mm_text, the X coordinate is increased to the right. The Y coordinate is increased down, (0, 0) above the left, DC, every point is the screen A pixel on the top. Maybe you will think that it is best understood in this way, but a point and pixel correspondence seems to be normal on the screen, but it will be very abnormal on the printer. Because our figure is in order units and the printer is much smaller than the display is high than the display (800DPI 800 points per inch), it will look small on the printer. This needs to increase the workload for printing another code. If each point corresponds to 0.1 mm, then the graphics on the screen will be as large as the printed graphics. The mapping mode can be specified by int CDC :: SetMapMode (int NmapMode), which is available in the following:

MM_HIENGLISH corresponds to 0.001 "Each Logical Unit IS Converted to 0.001 Inch. Positive X is to the right; posTIIVE Y IS UP.

MM_HIMETRIC corresponds to 0.001 mm Each Logical Unit IS Converted to 0.01 Millimeter. Positive x is to the right; posTIIVE Y IS UP.

MM_LOEENGLISH corresponds to 0.01 "Each Logical Unit IS Converted to 0.01 Inch. Positive X is to the right; posTIIVE Y IS UP.

MM_LOMETRIC corresponds to 0.001 mm Each Logical Unit IS Converted to 0.1 Millimeter. Positive x is to the right; posient Y is Up.

MM_TEXT pixels correspond to Each Logical Unit IS Converted to 1 Device Pixel. Positive x is to the right; posient y is down.

The above number of maps of mapping the default origin are above the left top of the screen. In addition to MM_Text, the X coordinate is increased to the right, the Y coordinate increases, and the natural coordinates are consistent. So pay attention to when mapping should be used to use a negative coordinate. Moreover, the above mappings are the ratio of X-Y or the like, i.e., the same length is in the X, and the length displayed on the Y axis is the same. Watch different mapping renderings Download Sample

Another mapping method is mm_anisotropic, which may specify different growth ratios. When setting this mode, you must call CSIZE CDC: SetWindowExt (Size Size) and CSIZE CDC :: SetViewPortext (Size Size) to set the growth ratio. The long-width ratio is determined according to the ratio of the two set aspects. The long-width ratio before and after a code comparison map is given below:

OnDraw (CDC * PDC) {CRECT RCC1 (200, 0, 400, 200); PDC-> FillSolidRect (RCC1, RGB (0, 0, 0, 0, 255)); PDC-> setmapmode (mm_anisotropic); csize sizeo; sizeo = PDC-> setWindowext (5, 5); Trace ("WINEXT% D% D / N", SIZEO.CX, SIZEO.CY); SIZEO = PDC-> setViewPortext (5, 10); Trace ("Viewext% D% D / N", Sizeo. CX, SIZEO.CY); CRECT RCC (0,0,200,200); PDC-> FillsolidRect (RCC, RGB (0, 128, 0));

The graphic drawn on the above code will be a rectangle. Watching Rendering Download Sample Finally, you can reset the origin by calling CPoint CDC :: SetViewPortorg (Point Point), which is displaced relative to the coordinate. For example, you set the origin in (20, 20), then the original (0,0) becomes (-20, -20).

Copyright 怡 洋 http://www.vchelp.net/

2.6 polygons and clipping regions

The polygon is also a GDI object, which is equally complied with the rules of other GDI objects, but usually do not select it in DC. There are CRGNs in the MFC in the MFC. The polygon is used to represent a different area of ​​the rectangle, and the rectangle has a similar operation. Such as: Detect whether a point is internally, and operation, etc. In addition, a minimum rectangle containing this polygon is obtained. Let's introduce a member function of a polygonal shape:

CreateRectrGN creates a polygon cretelllipticRGN by a rectangle Create a polygon CreatePolygonRGN Create a polygon PtinRegion with multiple points, whether there is two polygons of internal combinergn and equally two polygons, etc.

The meaning of speaking polygons in this section is to increase efficiency when it is played in the window. Because the cause of the window redraw is a certain area failed, the area of ​​the failure is expressed in a polygon. Assuming that the window size is 500 * 400 The other window above (0, 0, 10, 10) is moved to (20, 20, 30, 30), and the area is invalid, And you only need to redraw this part of the area instead of all areas, so your program's execution efficiency will increase.

By calling the API function int getClipRGN (HDC HDC, HRGN HRGN), you can get the failure area, but it is generally not so accurate, just get the minimum rectangle containing the area, so Int CDC :: getClipbox (LPRECT LPRECT) ) Complete this feature.

Copyright 怡 洋 http://www.vchelp.net/

3.1 Documentation and Message Transfer Law between Document View Frame Window

In the MFC, M $ introduces the concept of document-viewing structure, the document is equivalent to the data container, and the window that views the data is displayed or the window interacts with the data. (This structure is in the MFC OLE, and the ODBC development is more expanded) so a complete application is generally consisting of four classes: CWINAPP application classes, CFrameWnd window frame classes, cDocument document classes, CView view class. (Support for VC6 without document - Application)

CWINAPP will create a CFrameWnd Framework window instance when the program is running, and the Frame window will create a document template, then have a document template to create a document instance and view instance, and associate both. Generally speaking, we only need to operate documents and visual operations, and the various behaviors of the framework have been arranged by MFC without human intervention. This is also the intention of M $ design document - the spiritual structure, let us pay attention to finish The task is discharged from the interface writing.

One document is applied to the application, but a document can contain multiple views. Only one frame window is used in an application, and there may be multiple MDI sub-windows for multi-document interfaces. Each look is a sub-window, the parent window in a single document interface is a frame window, in the multi-document interface, the parent window is the MDI sub-window. A multi-document application can contain multiple document templates, one template defines a correspondence between a document and one or more views. The same document can belong to multiple templates, but only one document is allowed in a template. The same approach can also belong to multiple document templates. (I don't know if I said clearly)

Next, look at how to get a pointer to various objects in the program:

Global Functions AFXGetApp You can get the CWINAPP application class pointer AFXGetApp () -> m_pmainwnd is in the Frame window pointer in the frame window: cfraMew :: getActiveDocument Get the current activity document pointer in the frame window: cframeWnd :: getActiveView gets the current activity Picture pointer in the view : CView :: getDocument Get the corresponding document pointer in the document: cdocument :: getFirstViewPosition, cdocument :: getNextView is used to traverse all and document associations. In the document: cdocument :: getDoCtemplate Get the Document Template Pointer in the Multi-Document Interface: cmdiframeWnd :: MDiGetAn Gets the current active MDI sub-window Generally speaking users enter messages (such as menus selection, mouse, keyboard, etc.) If it is not processed, it will be sent to the Framework window. So defining a message mapping is defined in the view, if an application has multiple views while the current activity does not process the message, the message will be sent to the frame window.

Copyright 怡 洋 http://www.vchelp.net/

3.2 Receiving User Enter

Receive mouse inputs in the view:

The mouse message is the message we often need to process. The message is divided into: mouse movement, button press / release, double click. Use ClassWizard to easily add these message mappings, and the processing of each message is explained below.

WM_MOUSEMOVE corresponds to ONMOUSEMOVE (uint nflags, cpoint points), NFlags indicates a message of current buttons, and you can detect by "Bits".

The MK_Control Ctrl key is pressed to set if the ctrl key is down.

MK_LBUTTON mouse left button is pressed to set if The Left Mouse Button Is Down.

MK_MBUTTON mouse button is pressed to set if the mouse mouse button is down.

MK_RBUTTON mouse right button is pressed to set if the right mouse button is down.

The MK_SHIFT SHIFT button is pressed to set if the shift key is down. Point represents the device coordinates of the current mouse, the coordinate origin corresponds to the upper left corner.

WM_LBUTTONDOWN / WM_RBUTTONDOWN The corresponding function is the same for the ONLBUTTONDOWN / ONRBUTTONDOWN (UINT NFLAGS, CPOINT POINT) parameters and onMouseMove.

WM_LBUTTONUP / WM_RBUTTONUP The corresponding function is the same for ONLBUTTONUP / ONRBUTTONUP (UINT NFLAGS, CPOINT POINT) parameters and onMouseMove.

WM_LBUTTONDBLCLK / WM_RBUTTONDBLCLK / WM_RBUTTONDBLCLK (mouse left / right-click double click) The corresponding function is the same as that of ONLBUTTONDBLCLK / OnRButTondBlClk (Uint Nflags, CPoint Point).

Let's use a pseudo code to explain the usage of these messages:

The role of the code is to pull a rectangular global bool fdowned with the mouse; / / Whether to pull the global cpoint ptdown; // Press the position of Global Cpoint Ptup; // Loosen

ONLBUTTONDOWN (UINT NFLAGS, CPOINT) {fdowned = true; ptup = Ptdown = Point; DrawRect (); ...} OnMouseMove (uint nflags, cpoint point) {if (fdowned) {drawRect (); // Restore last time Drawn rectangular PTUP = POINT; DrawRect (); // Painting New Rectangle}} ONLBUTTONUP (UINT NFLAGS, CPOINT POINT) {if (fdowned) {DrawRect (); // Restore the rectangular PTUP = POINT in the last drawn; DrawRect (); // Draw new rectangular fdowned = false;}}

DrawRect () {// Draw PTDOWN, PTUP tagged rectangular CClientDC DC (this); MakeRect (PTDown, PTUP); setRop (not); RECT ();

Coordinate inter-coordinate conversion: In the above function, the Point parameters correspond to the device coordinates of the window, we should distinguish between the device coordinates and logical coordinates, in Figure 32_G1 Since the scroll bar is used in the window, the incoming device coordinate corresponds to The coordinates of the upper left corner of the current window do not consider whether it is scrolling, and the logical coordinates must consider scrolling the corresponding coordinates, so I use the yellow line virtual to express a logical coordinate area. It can be seen that the coordinate value after scrolling is different. This rule is equally applicable to the window of the mapping mode. It is assumed that you set the mapping mode to 0.01 mm per point, then the logic coordinate corresponding to the device coordinate It also needs to be recalculated. This conversion needs to be written to a code. Fortunately, the system provides the DPTOLP, LPTODP of the DPTOLP, LPTODP, which gives the code completion of the device coordinates to logic coordinates.

CPoint Cyourview :: FromDP (CPoint Point) {CClientDC DC (this); cpoint ptret = Point; dc.preparedc (); // must prepare DC first, this is to recculate the coordinate when using scrolling

// If you have a different mapping method, you need to set DC.SETMAPMODE (...) // dc.dptolp (& ptret); // DP-> LP for converting Return PTRET;}

In Fig. 32_G1, the blue line is marked is a client area of ​​the screen area, the red line mark. With ScreenToClient, ClientToscreen can convert coordinates between these two areas.

Receive the keyboard input in the view:

The keyboard message is three: The keyboard is pressed / released, and the character is entered. The input character is equivalent to the characters that directly get the user input. This is transmitted when the keyboard is pressed / released when the button status is changed.

The function corresponding to the WM_CHAR is onchar (uint nchar, uint nrepcnt, uint nflags), where nchar is the character pressed, indicating that the number of keys equivalent to the time when it is loose, and the different bits in NFLAGS represent different meanings. It is generally not used here.

The function corresponding to the WM_KEYDOWN / WM_KEYUP is onkeyDown / onkeyup (uint nchar, uint nrepcnt, uint nflags) Nchar represents the virtual code value of the button, such as VK_ALT is the Alt key, vk_control is the CTRL key. The meaning of NFLAGS is as follows: Value Description 0? Scan Code (Oem-Dependent Value). 8 Extended Key, Such AS A Function Key or A Key On The Numeric Keypad (1 if it is an extended Key). 9? 0 Not available 11? 2 Used INTERNALLY by Windows. 13 Context Code (1 if The Alt Key Is Held Down While The Key Is Pressed; Otherwise 0). 14 Previous Key State (1 if The Key Is Down Before The Call, 0 if the key IS UP). 15 Transition State (1 if the key is being reclass). The copyright has Wenyi Yanyo http://www.vchelp.net/

3.3 Using the menu

Using menu accepts user commands is a very simple interaction method, and it is also a very effective way. Usually menus are stored as a resource in a file, so we can use the resource editor to design a menu when designing. With regard to using the VC Design menu, I will not talk more, but you should try to enter text at the bottom prompt of the property dialog when writing the menu, which is not necessary, but the MFC is in the status bar and toolbar. In the case of this text, the format of the text is "Status Bar" / N Tools Tips ". Figure 33_G1

How do we face the task know how the user chooses a menu, what is the menu item? When the user selects a valid menu item, the system sends a WM_COMMAND message to the application, indicating the source in the parameters of the message. In the MFC, we only need to make a mapping, map a menu ID to a process function, Figure 33_G2. Here we handle menu messages in CVIEW derived classes, and I set two messages to the same ID, next to the role of these two mappings.

The role of the ON_COMMAND map is to call the specified processing function when the user selects the menu. Such as: ON_COMMAND (IDM_Command1, OnCommand1) calls the oncommand1 member function when the menu is selected.

ON_UPDATE_COMMAND_UI (IDM_COMMAND1, ONUPDATECOMMAND1) Map The pattern is to determine its status by calling the specified function when the menu is displayed. In this processing function you can set the allow / disable state of the menu, which shows what the string is in front of it. The parameter of the function is ccmdui * pcmdui, and ccmdui is a class that MFC is specifically provided by the update command. You can call

Enable Settings Allow / Disable Status SetCheck settings Whether to check the set of setText

Let me explain one example: I have a variable m_fselected in the cView derive class, and the message is handled in the view. When IDM_COMMAND1 is selected, the M_FSelected is logically non-operation, and when IDM_command2 is selected, it will be prompted; At the same time, idm_command1 determines the text displayed by the m_fselected menu and whether the symbol is checked in front, IDM_COMMAND2 determines the allow / disabling state of the menu according to the value of m_fselected. The following is the code and description: Download sample code 17kvoid cmenudview :: oncommand1 () {m_fselected =! M_fselected; trace ("command1 selected / n");}

Void cmenudview :: onupdateCommand1 (ccmdui * pcmdui) {pcmdui-> setCheck (m_fselected); // Decide Check status PCMDUI-> setText (m_fselected? ":" Currently ON "); // Decide Text}

Void cmenudview :: OnUpdateCommand2 (ccmdui * pcmdui) {// Decide whether to allow pcmdui-> enable (m_fselected);

Void cmenudview :: OnCommand2 () {// Select the prompt afxMessageBox ("You choose CommanD2");

Next, some ways to pass the code manipulation menu, there is a class cMenu in the MFC to handle and menu-related features. When generating a cMenu object, you need to install a menu from the resource, load Bool CMenu :: loadMenu (Uint NidResource), then you can make dynamic modifications to the menu, the functions involved are:

CMenu * GetSubmenu (int NPOS) Get a pointer to the submenu because a CMenu object can only represent a pop-up menu, if an item in the menu is also a pop-up menu, you need to get a pointer through this function. Bool appendmenu (uint nflags, uint nidnewItem = 0, LPCTSTR LPSZNEWITEM = NULL) Add an item at the end, NFLAG indicates an additional partition for MF_SEPARATOR, so that other two parameters will be ignored; MF_String means adding a menu item UidNewItem The menu ID command value; adds a pop-up menu item to the MF_POPUP, at this time uidnewitem is another handle HMenu. LpsznewItem is a menu text description. Bool InsertMenu (uint nPosition, uint nflags, uint nidnewItem = 0, LPCTSTSTSTSZNEWITEM = NULL) is used to insert a menu in the specified location, and the location is indicated by the variable nPosition. If NFLAGS contains MF_BYPosition, it indicates that inserted in the NPosition location, if the MF_BYCOMMAND is included in the menu inserted in the command ID is NPosition. Bool ModifyMenu (uint nPosition, uint nflags, uint nidnewItem = 0, LPCTSTSTR LPSZNEWITEM = NULL) is used to modify a list of places, if nflags contains MF_BYPosition, indicating the menu that modifies the NPosition location, if the MF_BYCOMMAND indicates that the modification command ID is NPosition. Menu. Bool RemoveMenu (uint nPosition, uint nflags) is used to delete a list of a location. If NFLAGS contains MF_BYPosition, it indicates the menu that deletes the NPosition location, if the MF_BYCOMMAND indicates the menu that the delete command ID is NPosition. Bool appendmenu (uint nflags, uint nidnewItem, const cbitmap * pbmp) and BOOL INSERTMENU (uint nPosition, uint nflags, uint nidnewItem, const cBitMap * PBMP) can add a bitmap menu, but such menus are selected when selected And not beautiful. (About an article on the use of the self-painted OwnerDraw menu, please refer to the self-painted menu of the self-painted menu) view, there is no menu, in the frame window, so it only uses AFXGetApp () -> m_pmainwnd-> getMenu () to get Applying menu pointer.

Finally, I will talk about how to pop up a menu in the program, you must first load a menu resource, you must get a pointer to the pop-up menu and then call Bool TrackPopUpMenu (uint nflags, int x, int y, cwnd * pwnd, lpcRect LPRECT = NULL) Popup menu, you need to specify (x, y) where the menu pops up, PWnd is the window pointer to the receiving command message. There is a code description method for downloading the sample code 17K below. Of course, for processing messages, you should mapping the menu command message in the window indicated by the PWND.

CMenu Menu; Menu.LoadMenu; cmenu * PM = menu.getsubmenu (0); cpoint pt; getCursorpos (& PT); PM-> TrackPopupnupMenu (TPM_LEFTALIGN, PT.X, Pt.Y, this); another The practice is to create a pop-up menu via CMenu :: CreatePopUpMenu () and then use the TRACKPOPMENU pop-up menu. The menu created using CreatePopupUpMenu can also add another menu as a pop-up. The following pseudo code demonstrates how to create a pop-up menu and pop up after modifying:

CMenu Menu1, Menu2; Menu1.CreatePopUpMenuMenu1.insertMenu (1) Menu1.insertmenu (2) Menu1.insertmenu (3)

Menu2.createPopupMenuMenu2.Appendmenu (MF_POPUP, 1, MENU1.DETACH ()) Add OR InsertMenu ... Menu2.insertmenu ("string desc"); menu.trackpopupmenu (...)

Copyright 怡 洋 http://www.vchelp.net/

3.4 Document, depending on the interaction between the framework

Generally speaking, the user's input / output is basically via via, but some exceptions may need to be effectively acting directly, while how to pass data in the case of multi-view.

When using the menu, you will find that when a menu is not mapped, it is forbidden. In the case of multi-view, the state and processing mapping of the menu is related to the current activity, so that the MFC can guarantee the correctness of the visibility. Various messages, but sometimes inconvenience. There is a solution to handle the message in the framework, which can also ensure that the current document can get the current message through the framework.

How to make the status update after the user is entered? This issue does not exist when a document corresponds to a view, but now there is a document corresponding to two views. How do I guarantee another view when I have an input? The MFC approach is to use documentation, because documentation manages the current and its contact, by it to notify the respective elements are the most appropriate. Let us look at two functions at the same time:

void CView :: OnUpdate (CView * pSender, LPARAM lHint, CObject * pHint) void CDocument :: UpdateAllViews (CView * pSender, LPARAM lHint = 0L, CObject * pHint = NULL) when UpdateAllViews document and this document is called associated All viewed onupdate will be called, and the parameters LHINT and PHINT will be passed. In this way, you can notify other brothers. Then there is another question: How to know that the view has changed in onupdate, this can take advantage of the phint parameter, as long as the caller assigns a value to the parameter, it is certainly possible to deliver more complex structures using this parameter. .

The initialization of the view, when a document is opened or a new document is newly built, the view :: OnInitialUpdate () will be called, you can initialize the performance by overloading the function, and call the parent class overnitialupdate before ending because This ensures that onupdate will be called.

Clear content in the documentation, when the document is turned off (such as exiting or the previous document clearing) VOID CDocument :: deleteContents () will be called, you can clean up the function by overloading the function.

It is especially important in the single document structure, because the software runs document objects and view objects will only be generated and deleted once. Therefore, the above two points and C objects should be constructed and clear. Finally, the role of document template (DOCTEMPLATE) is divided into two types of single document templates and multi-document templates, respectively, indicated by CSINGLEDOCTEMPLATE and CMULTIDEMPLATE, and the role of templates is to record documents, depending on the correspondence between the documents, depending on the framework. Another point is that the template can record the type of file that the application can open, select the correct document and see the correct document according to the information in the document template when the file is opened. The template is a relatively thoughtful concept. Generally, we don't need to operate directly.

When the user changes the data by modifying data, you should call GetDocument () -> setmodifiedflag (TRUE) Notification document data has been updated so that the user will automatically ask the user to save the data when turning off the document.

It seems that this section is a bit chaotic. If you look at what ideas and questions, please leave a message on the Vchelp forum, I will reply and modify this section as soon as possible.

Copyright 怡 洋 http://www.vchelp.net/

3.5 Using serialization to perform document reading and writing

In many applications we need to save data or read data from the media, which involves the operation of the file. We can use various document access methods to complete these work, but MFC also provides a simple way to read and write files - "Serialization". The serialization mechanism provides developers with a higher-level interface function, providing a file manipulation method that uses and transparent to byte streams, and for example, you can write a string into the file without the need for specific length. It is also the same when reading it. You can even operate the string array. With you automatically allocate memory, you can read / write data with your support. You can also write your own sequential classes as needed.

Serialization should be serialized support at the lowest level, that is, if you need to serialize a class, this class must support serialization. You only need the serialization function of this class when you read and write by serialization.

How to make the class serialize? You need the following work:

This class is derived from COBJECT. Include the Declare_Serial macro definition in the class declaration. Provide a default constructor. Implement the serialze function in the class using the import_serial to specify the class name and version number

The following code establishes a class of simple identity cards, and can also support serialization.

In hStruct strpid {char szname [10]; char szid [16]; struct strpid * pnext;}; class callpid: public cobject {public: declare_serial (callpid) CallPID (); ~ callpid (); public: // Serialization Related struct strpid * phead; // Other member functions void Serialize (carchive & ar);

IN CPPIMPLEMENT_SERIAL (CallPID, COBJECT, 1) // Version IS 1 = Gettotalid (); // Get the number of records in the list Arr <26; i ) ar << & ((Byte *) PiteM) i); // Write all data in a strPid}} else {///// Read data AR >> ITOTAL; for (int i = 0; i26; j ) ar >> * ((Byte *) pid) j); // read all data // modified linked lists in a strPid}}} Of course, the above code is very incomplete, but the problem can already be explained. Such CallPID is a class that can support serialization and can dynamically allocate memory according to the number of records. In serialization we use the Carchive class, which is used to provide read and write support in serialization, which overloads the << and >> operation symbols, and provides the read and write function to read and write the data.

Let's take a look at how to use serialization in the document, you only need to modify the Serialize (CARCHIVE & Ar) function of the document class, and call each Serial's serial to read and write. Of course, you can also read and write in the interior of the document class. The following code uses the serialization function to read and write data:

Class Cyourdoc: Public CDocument {Void Serialize (CARCHIVE & A); CSTRING M_SZDESC; CallPid M_AllPid; ......}

Void cyordoc :: serialize (carchive & ar) {{// Because CString defines the << and >> operation symbols for Custive, you can use >> and << ar <> m_szdesc;} m_allpid.serialize (ar); // Call the serialization function of the data class}

Copyright 怡 洋 http://www.vchelp.net/

3.6 Introduction to the various views provided in MFC

A rich view of the visual class is provided in the MFC, and each class is introduced below:

The CVIEW class is the most basic view class only supports the most basic operations.

CScrollView class provides a scrolling function, you can use the void CScrollView :: SetScrollSizes (int nMapMode, SIZE sizeTotal, const SIZE & sizePage = sizeDefault, const SIZE & sizeLine = sizeDefault) disposed rolling size, and the coordinates of the mapping mode. However, the coordinates need to be converted when drawing and receiving user input. See 3.2 Receiving User Enter.

The CFormView class provides the ability to define interfaces in the resource file and can bind the sub-windows and variables. Let the data exchange between variables and sub-windings through the Updatedata function.

CtreeView class uses the TreeCtrl interface as the vision interface, gets a reference to CTreeCtrl by calling CTreeCtrl & CtreeView :: gettreeCtrl () const.

CLISTVIEW class uses the ListCtrl interface as the vision interface, by calling CTreeCtrl & CtreeView :: gettreeCtrl () const to get the CLISTCTRL reference.

The CEDITVIEW class uses the Edit to receive user input, which has all functions of the input box. Get an Edit & Credit () Const by calling CEDIT & CEDITVIEW :: GetitCtrl () Const. Void CEDITVIEW :: SetPrinterFont (cfont * pfont) can set the print font. The CRICHEDITVIEW class as the view class of RICH Text Edit, provides the ability to display text according to the format, requiring CRICHEDITDOC support when using.

Copyright 怡 洋 http://www.vchelp.net/

4.1 Button

The button window (control) uses CButton in the MFC, and CButton contains three styles of buttons, Push Button, Check Box, Radio Box. So you need to specify the style of the button when you generate a button window using the CButton object.

Create button: BOOL CBUTTON :: Create (LPCTSTR LPSZCAPTION, DWORD DWSTYLE, CONST RECT & RECT, CWND * PPARETWND, UINT NID); where lpszcaption is the text displayed on the button, DWStyle is a button style, except for Windows style (such as WS_CHILD) | WS_VISUBLE | WS_BORDER) There are some styles dedicated to the button.

BS_AUTOCHECKBOX check boxes, will automatically change the status button Same as a check box, except that a check mark appears in the check box when the user selects the box; the check mark disappears the next time the user selects the box.

BS_AUTORADIOBUTTON round selection button, the button will automatically change state Same as a radio button, except that when the user selects it, the button automatically highlights itself and removes the selection from any other radio buttons with the same style in the same group.

The BS_AUTO3STATE allows the button to have three states: select, unselected, unselected Same as a three-state check box, Excepter That the box changes it.

BS_CHECKBOX Checkbox Creates A Small Square That Has Text Displayed To ITS Right (Unless this style is combined with the bs_lefttext style).

BS_DEFPUSHBUTTON default push button Creates a button that has a heavy black border. The user can select this button by pressing the ENTER key. This style enables the user to quickly select the most likely option (the default option).

Left Text BS_LEFTTEXT When combined with a radio-button or check-box style, the text appears on the left side of the radio button or check box.BS_OWNERDRAW since the draw button Creates an owner-drawn button. The framework calls the DrawItem member function . This is the cbitmapbutton class.

BS_PushButton Normal Button Creates a Pushbutton That Posts A WM_COMMAND MESSAGE TO The OWNER WINDOW WHEN THE USER SELECTS The Button.

BS_RADIOBUTTON round selection button Creates a small circle that has text displayed to its right (unless this style is combined with the BS_LEFTTEXT style). Radio buttons are usually used in groups of related but mutually exclusive choices.

The BS_3State allows the button to be three states: select, unselected, unselected Same as a check box, Except That the Box Can Be Dimmed AS Well As CHECKED. The Dimmed State Typically Is Used to Show That a check box has been disabled. Rect is The rectangular area occupied by the window, pParentWnd is the parent window pointer, NID is the ID value of the window.

Get / change button Status: There may be two states, select and unchecked for check buttons and round buttons. If the BS_3State or BS_AUTO3STATE style may appear: Unexpected, the button is displayed as gray. By calling int CButton :: getCheck () gets the currently selected, return 0: Unchecked, 1: Select, 2: Unexpected. Call Void CButton :: SetCheck (INT NCHECK); Set the current status.

Processing button message: To process the button message, the message map is required in the parent window, the mapping macro is the id value of the ON_BN_CLICKED (ID, the MemberFXN) ID, which is the NID value specified when creating. Processing function prototype is AFX_MSG Void Memberfxn ();

Copyright 怡 洋 http://www.vchelp.net/

4.2 Static Box

Static text controls are relatively simple, can be used as a display string, icon, and bitmap. Create a window to use member functions: BOOL CSTATIC :: Create (LPCTSTR LPSZTEXT, DWORD DWSTYLE, CONST RECT, CWND * PPARETWND, UINT NID = 0xfff); where DWStyle will indicate the style of the window, in addition to the style WS_CHILD in the child window Outside WS_VISIBLE, you can specify a special style for static controls.

SS_CENTER, SS_LEFT, SS_RIGHT indicates alignment of characters display. SS_GRAYRECT Displays a gray rectangle SS_NOPREFIX If the style is indicated, the character & will display directly, and & will use the escape character, & will not display, and after the characters will underline, if you need to display it directly, you must use && must use && . SS_BITMAP Display Bitchart SS_ICON Display Icon SS_CENTERIMAGE Image Creation Display Control Show text Utilize member function setWindowText / getWindowText is used to set / get the currently displayed text.

Controls the icon to use the member function seticon / geticon to set / get the currently displayed icon.

Control displayed bitmap utilizes member function setBitMap / getBitmap to set / get a bitmap currently displayed. The following segment demonstrates how to create a static window of a display bitmap and set a bitmap.

CStatic * pstaDis = new CStatic; pstaDis-> Create ( "", WS_CHILD | WS_VISIBLE | SS_BITMAP | SSCENTERIMAGE, CRect (0,0,40,40), pWnd, 1); CBitmap bmpLoad; bmpLoad.LoadBitmap (IDB_TEST); pstaDis -> setBitmap (bmpload.detach ());

Copyright 怡 洋 http://www.vchelp.net/

4.3 Edit Box

The Edit window is used to receive the user's most common control. Create a member function: BOOL CEDIT :: Create (LPCTSTSTR LPSZTEXT, DWORD DWSTYLE, CONST RECT, CWND * PPARETWND, UINT NID = 0xfff); where DWStyle will indicate the style of the window, in addition to the common style of the child window Outside WS_CHILD, WS_VISIBLE, you can specify a special style for the input control.

ES_AUTOHSCROLL, ES_AUTOVSCROLL indicates automatically scrolling when entering the text exceeds the display. ES_CENTER, ES_LEFT, ES_RIGHT Specify whether ES_MULTILINE allows multi-line input ES_PASSWORD to be password input box, if the style is indicated, the text is entered, whether it is * es_readonly is read-only ES_UPPPPPPPERCASE, ES_LOWERCASE Show uppercase / lowercase characters

Controlling text Using member function setWindowText / getWindowText is used to set / get the currently displayed text.

You can get / set the number of characters entered in the input box through getLimitText / setLimitText.

Since the user may select a certain piece of text while entering the Void Cedit :: Getsel (int & NStartChar, INT & NENDCHCHAR), by calling vid ced :: setsel (int NStartchar, Int Nendchar, Bool Bnoscroll = FALSE ) You can set the currently selected text range, if you specify nStartChar = 0 NendChar = -1, indicate all text. Void ReplaceSel (LPCTSTSTR LPSZNEWTEXT, BOOL BCANUNDO = FALSE) can replace the selected text to the specified text.

In addition, the input box also has some features related to the clipboard, void clear (); delete the selected text, void copy (); you can send the selected text into the clipboard, Void Paste (); insert the content in the clipboard The cursor position in the current input box, Void Cut (); it is equivalent to Copy and Clear.

Finally, introduce several common message mapping macro in the input box:

ON_EN_CHANGE Input box After updating the ON_EN_ERRSPACE input box Caigons to generate ON_EN_KILLFOCUS / ON_EN_SETFOCUS to generate ON_EN_KILLFOCUS / ON_EN_SETFOCUS When the input box is lost / gover input focus, the method used to generate the above message map is defined as: AFX_MSG Void Memberfxn () function And define a message mapping such as ON_NOTIFICATION (ID, MemberfxN). If you use the input box in the dialog box, Class Wizard will automatically list the relevant messages and automatically generate message mapping code.

Copyright 怡 洋 http://www.vchelp.net/

4.4 Scroll Bar

Scroll bar is generally not used alone because spinctrl can replace a part of the scroll bar, but if you need to generate a derived window, scroll bar or some use of some use. Create a scroll bar to use member functions: Bool Cedit :: Create (LPCTSTR LPSZTEXT, DWORD DWSTYLE, CONST RECT, CWND * PPARENTWND, UINT NID = 0xfff); where DWStyle will indicate the style of the window, in addition to the child window WS_CHILD, WS_VISIBLE, you can specify a dedicated style for scrolling strips.

The SBS_VERT style will create a vertical scroll bar. The SBS_HORZ style will create a horizontal scroll bar.

After creating a scroll bar, you need to call Void SetScrollRollRange Set the scroll range, int GetScrollPos () / int setscrollpos () is used to get the location of the current scroll bar.

Void Showscrollbar (Bool Bshow = true); used to display / hide the scroll bar.

BOOL EnableScrollbar (uint narrowflags = esb_enable_both) is used to set whether the arrow on the scroll bar is allowed. NarrowFlags can take the following values:

ESB_ENABLE_BOTH Two arrows are for allowed state ESB_DISABLE_LTUP / left arrows for disabled status ESB_DISABLE_RTDN, and the right arrow is forbidden. ESB_DISABLE_BOTH two arrows are forbidden states

If you need notifications when the scroll strip position is changed, you need to define the mapping of the message WM_VSCROLL / WM_HSCROLL in the parent window. A method for heavy-duty afx_msg void OnVScroll the parent window class (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar) / afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar * pScrollBar) used for message map macro: ON_WM_VSCROLL (), ON_WM_HSCROLL (), does not need to specify the ID of the scroll bar in the mapping macro because all scroll bars are processed by the same function. The third parameter on OnHScroll / ONVSCROLL indicates a pointer to the current scroll bar. The first parameter represents the action that occurs on the scroll bar, and the following values ​​are available:

SB_TOP / SB_BOTTOM has scrolled to the top / bottom SB_Lineup / SB_LINEDOWN Rolling up / down SB_PAGEDOWN / SB_PAGEUP Up / down scroll one page SB_THUMBPSITION / SB_THUMBTRACK scroll bar drag to a location, parameter NPOS indicates the current position (parameter NPOS in other cases Is invalid) SB_ENDSCROLL scroll bar drag completion (user loosening mouse) Copyright All rights Wenyi http://www.vchelp.net/

4.5 List box / check list box

The Listbox window is used to list a series of texts, each text occupies a line. Create a list window You can use the member function: Bool Clistbox :: Create (LPCTSTR LPSZTEXT, DWORD DWSTYLE, CONST RECT, CWND * PPARETWND, UINT NID = 0xfff); where DWStyle will indicate the style of the window, in addition to the style common to the child window Outside WS_CHILD, WS_VISIBLE, you can specify a special style for the list control.

LBS_MULTIPLESEL indicates that the list box can select Multi-line LBS_EXTendedsel at the same time can select multi-line LBS_SORT all rows to sort in alphabetical order by pressing the SHIFT / CTRL button.

You can add or remove rows after the list box is generated, you can use: int AddString (Uint Nindex) to add rows, int DeteString (int NINDEX, LPCTSTSTSTSTR LPSZITEM) to the specified position. void resetContent () can delete all rows in the list box. Get the number of rows in the current list box by calling int getCount ().

If you need to get / set the currently selected row, you can call int getcurseel () / int setcurseel (IND IIndex). If you indicate the style of choosing multiple lines, you need to call int getselcount () to get the number of rows selected, then int GetSelitems (INT NMAXITEMS, LPINT RGIndex) get all selected rows, parameter rgIndex is stored Array. Get the string of the specified row in the list box by calling int GetlbText (int NINDEX, LPTSTSTSTSTR LPSZTEXT).

Also by calling int FindString (INT NSTATAFTER, LPCTSTR LPSZITEM) can find the location of the specified character transmission in all rows, NSTARTAFTER indicates that the lookup starts from that line. INT SelectString (INT NSTARTAFTER, LPCTSTR LPSZITEM) can be selected to contain rows that specify strings.

Add a CCheckListBox class in the MFC 4.2, which is derived from CLISTBOX and has all features of CListBox, which can be added to a check box before each row. It must be noted that the LBS_OWNERDRAWFIXED or LBS_OWNERDRAWVARIABLE style must be specified when creating.

The style of check box can be set by Void SetCheckStyle (uint nstyle) / uint getCheckStyle (), and the check box can be referred to in the check box style. The check status of a row can be set by Void SetCheck (int NINDEX) / INT getCheck (INT NINDEX). About check box status can be referred to in 4.1 Button.

Last introduction to the list box several common message mapping macro: on_lbn_dblclk mouse Double-click the ON_EN_ERRSPACE input box Uncord memory When the memory generates ON_EN_KILLFOCUS / ON_EN_SETFOCUS to generate an ON_LBN_SELCHANGE selection when the input box is lost / given the input focus, change the above several message mappings The method is to define the prototype as: AFX_MSG Void Memberfxn (); and define a message map such as ON_NOTIFICATION (ID, MemberFXN). If you use the list box in the dialog box, Class Wizard will automatically list the relevant messages and automatically generate message mapping code.

Copyright 怡 洋 http://www.vchelp.net/

4.6 Combo Box / Combo Box EX

The combination window consists of an input box and a list box. Create a combination window to use member functions: BOOL Clistbox :: Create (lpctstr lpsztext, dword dWstyle, const, uint nid = 0xfff); where DWStyle indicates the style of the window, in addition to the style commonly used in child window Outside WS_CHILD, WS_VISIBLE, you can specify a special style for the list control.

CBS_DROPDOWN drop-down combination box CBS_DropDownList drop-down combo box, but in the input box cannot perform input cbs_simple input boxes and list boxs simultaneously display LBS_SORT all rows in alphabetical order

Since the list box contains a list box in the combo box, the functionality of the list box can be used, and if you can use: int AddString (Uint Nindex) to delete the specified line, int insertex, lpctstr lpszitem Insert the line into the specified location. void resetContent () can delete all rows in the list box. Get the number of rows in the current list box by calling int getCount ().

If you need to get / set the location of the currently selected row, Int getcurseel () / int setcurseel (INT IINDEX) can be called. Get the string of the specified row in the list box by calling int GetlbText (int NINDEX, LPTSTSTSTSTR LPSZTEXT).

Also by calling int FindString (INT NSTATAFTER, LPCTSTR LPSZITEM) can find the location of the specified character transmission in all rows, NSTARTAFTER indicates that the lookup starts from that line. INT SelectString (INT NSTARTAFTER, LPCTSTR LPSZITEM) can be selected to contain rows that specify strings.

In addition, the functionality of the input box can be used, as you can use: DWord getSel () / bool setEditsel (int NStartChar, int NendCha) gets or sets the selected character position in the input box. BOOL LIMITTEXT (INT NMAXCHARS) Sets the maximum number of characters that can be entered in the input box. The clipboard function of the input box can be used.

Last introduction to the list box several common message mapping macro:

Generating row selection list box ON_CBN_SELCHANGE ON_CBN_DBLCLK Double click when the list box to be ejected ON_CBN_DROPDOWN ON_CBN_KILLFOCUS / ON_CBN_SETFOCUS lost in the input box / input focus changes ON_CBN_EDITUPDATE obtained input box content is updated using the above several methods of mapping information is defined as the prototype: AFX_MSG Void MemberFXN (); and defines a message mapping of form such as ON_NOTIFICATION (ID, MemberfxN). If you use a combo box in the dialog, Class Wizard will automatically list the relevant messages and automatically generate message mapping code. In MFC 4.2, the combo box is enhanced, you can use imagelist in the combo box, there is a new class CCOMBOBOXEX (derived from CCOMBOBOX) to achieve this. Add some new member functions to the CCOMBOBOXEX class to implement new features: first you need to call CIMAGELIST * SETIMAGELIST (CIMAGELIST * PIMAGELIST); to set imagelist, then call int insertitem (const comboBoxExItem * PCBITEM); come to add line, where ComboBoxExItem is defined as follows:

Typedef struct {uint mask; int itX; int cchtextmax; int tent; int tentmax; int ost ost intelected; tent; lparam lparam;} comboBOBOXEXITEM, * PCOMBOBOXEXITEM;

You need to set mask = cbeif_image | cbeif_text, and set IIITEM to the insertion position, set PSZText to display the string, set the IIMAGE to the displayed icon index. The following code demonstrates how to insert: / * m_cbewnd is a bitmap that the CCOMBOX object M_List that has created is a ciMagelist object IDB_IMG is 16 * (16 * 4), each picture is 16 * 16 total 4 icon * / m_list. Create (IDB_IMG, 16, 4, RGB (0, 0, 0)); m_cbewnd.setimagelist (& M_List);

COMBOBOXEXITEM insItem; insItem.mask = CBEIF_IMAGE | CBEIF_TEXT; insItem.iItem = 0; insItem.iImage = 0; insItem.pszText = "Line 1"; m_cbeWnd.InsertItem (& insItem); insItem.iItem = 1; insItem.iImage = 1 Insitem.psztext = "line 2"; m_cbewnd.insertitem (& insitem);

Remove the row by calling int deleteItem (INT IIndex); By calling the Bool GetItem (Contly) / Bool SetItem (Const ComboBoxExItem * PCBITEM);

Copyright 怡 洋 http://www.vchelp.net/

4.7 Tree Ctrl

Tree control TreeCtrl and the list of list controls listed in the system are used in large numbers in the system, such as Windows Explorer is a typical example.

The tree control can be used for the structure of the tree, where there is a root point (root) and then there are many sub-nodes below, while each sub-node has one or more or no sub-nodes. The CTreeCtrl class is used in the MFC to encapsulate various operations of the tree control. Create a window by calling Bool Create (DWord DWSTYLE, UINT NID); Create a window, you can use the specific style of the following tree controls: TVS_HASLINES Draw a connection between the parent / sub-nodes Drawing cables Tvs_LinesTroot Drawing the connection between the root / sub-node to add a button before each node, which is used to indicate whether the current node has been expanded to the TVS_EDITLABELS node can be edited TVS_SHOWSELALWAYS to display the current selection when the focus is lost. Node TVS_DISABLEDRAGDROP does not allow DRAG / DROP TVS_NOTOOLTIPS without using the TooltiP display node display character with a handle (HTREEITEM) in the tree control, and the parameters that must be provided when adding nodes to the node. The parent node handle, (where only one root ROOT node can not be added, can not be deleted) Use HtreeItem INSERTITEM (LPCTSTSTR LPSZITEM, HTREEITEM HINSERTAFTER = TVi_last); you can add a node, pszitem is displayed Character, HParent represents the handle of the parent node, the currently added node will be behind the nodes represented by the HinsertAfter, return the value of the currently created node. The following code will establish a tree structure as follows: --- Parent1 --- Child1_1 --- Child1_2 --- Child1_3 --- Parent2 - Parent3

/ * Suppose m_tree is a CTREECTRL object, and the window has created * / htem = m_tree.insertitem ("parent1", TVi_root); add parent1hsubitem = m_tree.insertitem ("Child1_1" on the root node HITEM); // Add a sub-node hSUBITEM = m_tree.insertitem ("Child1_2", HITEM, HSUBITEM); // Add a sub-node on Parent1, ranking HSUBITEM = m_tree.insertItem = m_tree.insertitem (" Child1_3 ", HITEM, HSUBITEM;

HITEM = m_tree.insertitem ("Parent2", TVi_root, HITEM); HITEM = m_tree.insertitem ("Parent3", TVi_root, HITEM)

If you want to add a small icon before each node, you must call CIMAGELIST * SETIMAGELIST (CIMAGELISTTTTYPE); indicating the imagelist used, NimageListType is TVSIL_NORMAL. Use the picture in the call to complete the image to be used in the image of ImageList. Then call HTREEITEM InsertItem (LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST); add node, nImage as a picture ID is used when the node is not selected, nSelectedImage when the node is selected by Use the picture number. The following code demonstrates the setting of ImageList. / * m_list is a bitmap for the CImageList object IDB_Tree is 16 * (16 * 4), each picture is 16 * 16 total 4 icons * / m_list.create (IDB_TREE, 16, 4, RGB (0,0,0) ); m_tree.setimagelist; m_tree.insertitem ("PARENT1", 0, 1); // Add, selected display icon 1, unchecked icon 0 In addition, CTreeCtrl also provides some functions for getting / Modify the status of the control. HtreeItem getSelectedItem (); will return the handle of the currently selected node. Bool SelectItem (HTREEITEM HITEM); selects the indicated point. Bool GetItemImage (HtreeItem Hitem, INT & NIMAGE, INT & NSELECTEDIMAGE) / BOOL SETITEMIMAGE (INT NSEEM HITEM, INT NIMAGE, INT NSELECTEDIMAGE) is used to get / modify the icon index used by a node. CString GetItemText (HTREEITEM hItem) / BOOL SetItemText (HTREEITEM hItem, LPCTSTR lpszItem); for obtaining / modifying a display character node. Bool DeleteItem (HTREEITEM HITEM); used to delete a node, bool deleteallItems (); all nodes will be deleted.

Also if you want to traverse the tree, you can use the following function: htreeItem getrootItem (); get root node. HtreeItem getChildItem (HTREEITEM HITEM); gets a child node. HtreeItem getPrevsiblingItem / getNextSiblingItem (HtreeItem HITEM); gets the top / next brother node with indicated nodes. HtreeItem getParentItem (HTREEITEM HITEM); getting a parent node.

The message mapping of the tree control uses the ON_NOTIFY macro, the form is like: ON_NOTIFY (WNOTIFYCODE, ID, MEMBERFXN), WNOTIFYCODE is the notification code, the ID is the window ID generated by the message, Memberfxn is the process function, the prototype of the function is like void onxxtree (nmHDR * PNMHDR, LRESULT * PRESULT, where PNMHDR is a data structure, which needs to be converted to other types of structures when specifically used. For the tree control, the value and the corresponding data structure are:

TVN_Selchanged Send after the selected node, the structure used: NMTreeView TVn_iteMexpanded is sent after a node is expanded, the structure used: NMTreeView TVn_beginlabeledit Sends when editing node characters, the structure used: NMTVDispinfo TVn_ENDLABELEDIT End Edit Node When the character is sent, the structure used: NMTVDISPINFO TVN_GETDISPINFO is sent when a certain node information is required, (such as getting a node display character): NMTVDispinfo About ON_NOTIFY has a lot of content, will be explained in detail in future content. About the character displayed by dynamic providing node: First, you need to indicate that the LPSZITEM parameter is: lpstr_textcallback when you add a node. When the control displays the node, the desired character will be obtained by sending TVN_GETDISPINFO, and the parameter PNMHDR is converted to LPNMTVDispinfo when processing the message, and then populates Item.psztext. But what we know about this node, my approach is to set its LPARAM parameters after adding a node, and then use this parameter to find the corresponding information when providing information. The following code illustrates this method:

Char Szout [8] [3] = {"No.1", "No.2", "No.3"};

// Add Node HtreeItem Hitem = m_tree.insertitem (LPSTR_TEXTCALLBACK, ...) M_Tree.SetItemData (HITEM, 0); HITEM = m_tree.insertitem (LPSTR_TEXTCALLBACK, ...) M_Tree.setItemData (HITEM, 1); // processing the message void CParentWnd :: OnGetDispInfoTree (NMHDR * pNMHDR, LRESULT * pResult) {TV_DISPINFO * pTVDI = (TV_DISPINFO *) pNMHDR; pTVDI-> item.pszText = szOut [pTVDI-> item.lParam]; // get need lParam The position displayed in the array * PRESULT = 0;}

About editing node display character: First need to set the TVS_EDITLABELS style of the tree control, the control will send TVN_BEGINLABELEDIT when you start editing, you can cancel the editing by returning true in the process function, after the editing is completed Send TVN_ENDLABELEDIT, you need to convert parameter pnmhdr to lpnmtvdispinfo when processing the message, and then get the edited characters through the item.psztext, and reset the display character. If the editor cancels the variable is NULL in the middle. The following code shows how to handle these messages:

// message processing TVN_BEGINLABELEDITvoid CParentWnd :: OnBeginEditTree (NMHDR * pNMHDR, LRESULT * pResult) {TV_DISPINFO * pTVDI = (TV_DISPINFO *) pNMHDR; if (pTVDI-> item.lParam == 0); // determines whether to cancel the operation * pResult = 1; else * pResult = 0;} // message processing TVN_BEGINLABELEDITvoid CParentWnd :: OnBeginEditTree (NMHDR * pNMHDR, LRESULT * pResult) {TV_DISPINFO * pTVDI = (TV_DISPINFO *) pNMHDR; if (pTVDI-> item.pszText == NULL); // Determine if the editing of M_Tree.SetItemText (PTVDI-> ITEM, PTVDI-> PSZText); // Reset the display character * PRESULT = 0;} The message mapping must be made by the method described above. Perform in the parent window (all messages of the same WM_Notify need to be processed in the parent window).

Copyright 怡 洋 http://www.vchelp.net/

4.8 List Ctrl

The list control can be seen as a function-enhanced listbox, which provides four style, and can also display a column of multi-medium attribute values ​​at the same time. The CListCtrl class is used in the MFC to encapsulate the various operations of the list control. Create a window by calling Bool Create (DWord DWStyle, Const Rect, CWnd * PParentWnd, Uint Nid), creating a window, you can use the following list controls in the DWStyle:

LVS_ICON LVS_SMALLICON LVS_LIST LVS_REPORT These four style determine the appearance of the control, and only one of them, respectively: large icon display, small icon display, list display, detailed report Display the display character of the LVS_EDITLABELS node can be edited, for the report Style is for editable only to the first column. LVS_SHOWSELALWAYS also displays the currently selected node LVS_SINGLESEL while losing the focus. Only one of the first items you need to set the list control, if you use a large icon to display the style, you need to call as follows: CImageList * SetImageList (CIMAGELIST * PIMAGELIST, LVSIL_NORMAL); If you use other three style display instead of you don't want to make any settings, you can do any settings, otherwise you need to call as follows: CIMAGELIST * SETIMAGELIST (CIMAGELIST * PIMAGELIST, LVSIL_SMALL);

By calling int INSERTITEM (INT NITEM, LPCTSTSTSTSTSTSZZITEM); you can insert an insertion in the NITEM in the list control, LPSZITEM is a display character. In addition to the other three styles except the LVS_Report style, you can only call InsertItem, but if you use the report style, you must first set the column information in the list control.

By calling int INSERTCOLUMN (Int Ncol, LPCTSTSTSZCOLUMNHEADING, INT NFORMAT, INT NWIDTH, INT NSUBITEM); can be inserted. ICOL is the list of columns, from zero, lpszcolumnheading is the displayed column name, NFORMAT is a display alignment, NWidth is the display width, and NSUBITEM is the column index assigned to the column. In multiple columns, you need to indicate that the display character in each column is indicated to each column, by calling Bool SetItemText (int NITEM, INT NSUBITEM, LPTSTR LPSZTEXT); you can set the display character for each column. NIITEM is the location of the set item, nsubitem is a column location, and LPSZText is a display character. The following code demonstrates how to set multiple columns and insert data:

M_List.setimagelist (& M_Listsmall, lvsil_small); // Set imaginglistm_list.insertColumn (0, "COL 1", LVCFMT_LEFT, 300, 0); // Setting column M_List.insertColumn (1, "COL 2", LVCFMT_LEFT, 300, 1 ); M_List.insertColumn (2, "COL 3", LVCFMT_LEFT, 300, 2);

m_list.insertitem (0, "item 1_1"); // Insert a row m_list.setitemtext (0, 1, "Item 1_2"); // Set the display character m_list.setitemtext of the row of the row (0, 2, " Item 1_3 ");

In addition, CListCtr also provides some functions to get the status of / modify the control. ColorRef GetTextColor () / Bool SetTextColor (ColorRef CR); used to get / set the character color. ColorRef GetTextBkcolor () / Bool SetTextBkcolor (ColorRef CR); used to get / set the background color. Void setItemcount; used to get the number of items to add in the list. Bool DeleteItem (INT NITEM); used to delete a one, Bool deleteAllItems (); will delete all items. Bool SetBkimage (Hbitmap HBM, Bool FTILE, INT XOFFSETPERCENT); for setting up background bitmap. CSTRING GETITEMTEXT (INT NITEM, INT NSUBITEM); used to get a display character of a certain item.

The message mapping of the list control also uses the ON_NOTIFY macro, the form is like: ON_NOTIFYCODE, ID, MEMBERFXN, WNOTIFYCODE is the notification code, the ID is the window ID that generates the message, Memberfxn is the process function, the prototype of the function is like Void ONXXLIST (NMHDR * PNMHDR, LRESULT * PRESULT, where PNMHDR is a data structure, which needs to be converted to other types of structures when specifically used. For the list controls, the value and the corresponding data structure are:

LVN_BEGINLABELEDIT is sent when an editing character is started, and the structure used: Nmlvdispinfo LVN_ENDLABELEDIT is sent when an editing character is ended, the structure used: Nmlvdispinfo LVN_GETDISPINFO is sent when an item is required, (if you get a display character): Nmlvdispinfo has a lot of content about ON_NOTIFY, which will explain in detail in future content. About dynamically providing characters displayed: First, you need to indicate that the LPSZITEM parameter is: lpstr_textcallback. When the control displays the node, the desired character is obtained by sending TVN_GetDispinfo, and the parameter PNMHDR is converted to LPNMLVDISPINFO before processing the message, and then pops the item.psztext. By Item in Item, ISUBITEM can know that the currently displayed is. The following code demonstrates this method:

Char Szout [8] [3] = {"No.1", "No.2", "No.3"};

// add node m_list.InsertItem (LPSTR_TEXTCALLBACK, ...) m_list.InsertItem (LPSTR_TEXTCALLBACK, ...) // message processing void CParentWnd :: OnGetDispInfoList (NMHDR * pNMHDR, LRESULT * pResult) {LV_DISPINFO * pLVDI = (LV_DISPINFO *) PNMHDR; PLVDI-> Item.psztext = Szout [PTVDI-> Item.iItem]; // Get the location you need to display in an array via IIITEM * PRESULT = 0;}

About editing a display character: (only in the report style is only valid for the first column) First, you need to set the list control of the LVS_EDITLABELS style. When you start editing, the control will send LVN_BEGINLABELEDIT, you can return to True in the process function. Cancel the next editing, send LVN_ENDLABELEDIT after the editing is complete, you need to convert the parameters PNMHDR to lpnmlvdispinfo when processing the message, and then get the edited characters by it, and reset the display character. If the editor cancels the variable is NULL in the middle. The following code shows how to handle these messages:

// message processing LVN_BEGINLABELEDITvoid CParentWnd :: OnBeginEditList (NMHDR * pNMHDR, LRESULT * pResult) {LV_DISPINFO * pLVDI = (LV_DISPINFO *) pNMHDR; if (pLVDI-> item.iItem == 0); // determines whether to cancel the operation * pResult = 1; else * pResult = 0;} // message processing LVN_BEGINLABELEDITvoid CParentWnd :: OnBeginEditList (NMHDR * pNMHDR, LRESULT * pResult) {LV_DISPINFO * pLVDI = (LV_DISPINFO *) pNMHDR; if (pLVDI-> item.pszText == NULL); // Determine if you have canceled M_List.SetItemText (PLVDI-> Item.iItem, 0, PLVDI-> PSZText); // Reset Display Character * PRESULT = 0;}

The message mapping made by the method described above must be performed in the parent window (all messages of WM_NOTIFY need to be processed in the parent window). How to get the current selection location: There is no function similar to the getCursel () in the list control, but can be called getNextItem (-1, lvni_all | lvni_selected); get the selected item location.

Copyright 怡 洋 http://www.vchelp.net/

4.9 TAB CTRL

Tab property page controls can add different pages in a window and then notifications when changing in page. Use the CTabCtrl class in the MFC to encapsulate various operations of the property page control. Create a window by calling BOOL CREATE (DWord DWSTYLE, CONST RECT, CWND * PParentWnd, Uint Nid), and the DWStyle can use the specific style of the following property page control:

TCS_BUTTONS Use buttons to indicate page Select Page TCS_MULTILINE Branch Display Page Select Location TCS_SINGLINE Only uses a line display page Select location After the control is created, you can add a page to you can use, add the page function to: BOOL INSERTITEM (Int Nitem, lpctstr lpszitem) NITEM is position, starting from zero, LPSZITEM is the text displayed on page. If you want to display an icon at the page selection location, you can call Bool InsertItem (int NIMAGE); NIMAGE indicates the location of the picture used. (You must call CIMAGELIST * SETIMAGELIST (CIMAGELIST * PIMAGELIST); set the correct imagelist

In addition, CTabCtrl also provides a number of functions for receiving / modifying controls. INT getcurseel () / int setCuRSel (INT NITEM); used to get / set the currently selected page location. Bool DeleteItem (Int Nitem) / Bool DeleteAllItems (); Used to delete the specified / all page. Void RemoveImage (Int nimage); used to delete icons on a page selection location.

The message mapping of the property page control also uses the ON_NOTIFY macro, the form is like: ON_NOTIFY (WNOTIFYCODE, ID, MEMBERFXN), WNOTIFYCODE is the notification code, ID is the window ID generated by the message, Memberfxn is a process function, the prototype of the function is like Void ONXXTAB (NMHDR * PNMHDR, LRESULT * PRESULT, where PNMHDR is a data structure, which needs to be converted to other types of structures when specifically used. For the list controls, the value and the corresponding data structure are:

TCN_SELCHANGE is sent after the current page changes, the structure used: nmHDR TCN_SELCHANGING Send the change when the current page changes can prohibit the change of the page by returning true, the structure used: NMHDR

Generally speaking, you need to hide some of the current sub-windows when changing in the current page, and display other sub-windows. The pseudo code below demonstrates how to use the property page control:

CParentWnd :: OnCreate (...) {m_tab.create (...); m_tab.insertitem (0, "Option 1"); m_tab.insertitem (1, "Option 2"); Create A Edit Box as the m_tab's Child Create a static box as the m_tab's child edit_box.showwindow (sw_show); // Edit Box at the first page of the property page static_box.showwindow (sw_hide); // static box at the second page of the property page} void cparentWnd :: OnselectChangeTab (NMHDR * PNMHDR, LRESULT * PRESULT) {// Process page Select changed message if (m_tab.getcurseel () == 0) {// According to current page Display / hide different sub-window Edit_box.showWindow (sw_show) Static_box.showwindow (sw_hide);} else {// edit_box.showwindow (sw_hide); static_box.showwindow (sw_show);}}}}}} 闻 怡 怡 怡 http://www.vchelp.net/

4.a Tool Bar

Tools are also commonly used controls. The CToolbar class is used in the MFC to encapsulate various operations of the toolbar control. Create a window by calling BOOL CREATE (CWND * PParentWnd, DWord DWStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP, UINT NID = AFX_IDW_TOOLBAR); create a window, you can use the following toolbar controls in DWStyle:

The CBRS_TOP toolbar on the top of the parent window The bottom CBRS_FLOATIN tool bar in the parent window is the step of floating creation of a toolbar: first create a window first, then use Bool LoadToolbar (lpctstr lpszResourceName; directly from resources); Enter the toolbar, or by loading the bitmap and specify the ID of each button, the specific code is as follows:

UINT UID [5] = {IDM_1, IDM_2, IDM_3, IDM_4, IDM_5}; m_toolbar.create (pparentWnd); m_toolbar.loadbitmap (idb_toolbar); m_toolbar.setsizes (CSIZE (20, 20), CSIZE (16, 16)) ; // Set the size m_toolbar.setButtons (UID, 5) of the button large size and button.

AppWizard will generate the code of the toolbar at the same time when generating the code, and can also support the docking function. So it is generally not required to operate the tool bar object.

The button on the toolbar is pressed and sent to the parent window. The menu message is the same, so you can use the ON_COMMAND macro to map, the button in the toolbar also supports the related operations of ON_UPDATE_COMMAND_UI, such as setcheck, enable, you can put the button It is as an identical ID menu item on the menu.

In the later chapter 4.D uses AppWizard to create and use Toolbar StatusBar Dialog Bar to give the method.

Copyright 怡 洋 http://www.vchelp.net/

4.B Status Bar

Status bars are used to display some prompt characters. The CSTATUSBAR class is used in the MFC to encapsulate the various operations of the status strip control. By calling BOOL Create (CWnd * pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, UINT nID = AFX_IDW_STATUS_BAR); create a window, dwStyle can use some of the following status bar control special style: CBRS_TOP status bar at the top of the parent window TCBRS_BOTTOM The steps to create a state bar at the bottom of the parent window: first create a window using Create, then call Bool Setindicators (consT); set the ID of each part on the status bar, the specific code is as follows:

UINT UID [2] = {ID_SEPARATOR, ID_INDICATOR_CAPS}; m_stabar.create (pparentWnd); m_stabar.setindicators (UID, 2);

You can get the text displayed on / set the status strip by CString getPaNEText (int NINDEX) / BOOL SetPanetExt (INT NINDEX, LPCTSTSTSTSZNEWTEXT, BOOL BUPDATE = TRUE).

TIP: It is best to set all the parties in the status bar when creating a status bar (except for the ID of the MFC Customized Several ID), which is called the Void SetPaneInfo after the generation is generated. , Uint nstyle, int cxwidth; changing its style, ID and width.

AppWizard also generates the code of the status bar at the same time when generating the code. So generally do not need to create a status bar object directly. In addition, the command prompt on the menu is automatically displayed on the status bar (must be defined in the resource), so it is not necessary to display text.

Status strip supports the related operations of ON_UPDATE_COMMAND_UI, such as setText, enable.

In the later chapter 4.D uses AppWizard to create and use Toolbar StatusBar Dialog Bar to give the method.

Copyright 怡 洋 http://www.vchelp.net/

4.c Dialog Bar

Dialog Bar is similar to a dialog that is attached to the frame window. Since Dialog Bar can be edited using the resource editor, it is convenient to use it, and you can position the sub-window on the Dialog Bar when designing. Used to display some prompt characters. The CDIALOGBAR class is used in the MFC to use the various operations of the Dialog Bar control. Create a window, NidTemplate is a dialog resource, NStyle, which can use the window ID corresponding to the Dialog Bar, NStyle, the NStyle control, the NSTYLE, the NStyle, which is the window ID corresponding to the Dialog Bar. style:

CBRS_TOP DIALOG BAR TCBRS_BOTTOM DIALOG BAR at the top of the parent window At the bottom of the parent window CBRS_LIALOG BAR in the parent window CBRS_RIGHT DIALOG BAR in the parent window The right part of the Dialog Bar requires mapping and processing in the parent window. For example, the buttons on the Dialog Bar need to perform on_bn_clicked or on_command mapping in the parent window. The input box on the Dialog Bar can perform an ON_EN_CHANGE, ON_EN_MAXTEXT and other input boxes in the parent window. Mapping.

Dialog Bar supports the related operations of on_update_command_ui, such as setText, enable. In the later chapter 4.D uses AppWizard to create and use Toolbar StatusBar Dialog Bar to give the method.

Copyright 怡 洋 http://www.vchelp.net/

4.D uses AppWizard to create and use Toolbar Statusbar Dialog Bar

The runtime program interface is shown in the interface. The program has a toolbar for displaying two command buttons, one for demonstrating how the button is inspected, and the other is disabled / allowed according to the status of the first button. (Set check status and allowed status through onupdateCommand) In addition, there is an input box and button on the Dialog Bar. The prohibition / allowance of the two sub-windings is also determined according to the status status on the toolbar, when Press Dialog Bar The text content in the input box will appear when the button is button. The first part of the state bar is used to display various prompts, and the second part is used to display the current time with onupdateCommand. At the same time, in the program, how to set up a command interpretation of the menu item (will display the first part of the status bar) and how to set the toolbar prompt (using a small Tooltip window).

Generating App: Generate an MFC engineering, legend, and set to a single document interface legend, finally select the toolbar, status and rebar support, legend

Edit menu: Use Resource Editor to remove the extra menu and add a new pop-up menus and three sub-menus, legends, namely: Name ID Description Character Check IDM_CHECK SetCheck Demo / nSetCheck Demo Disable IDM_DISABLE Disable Demo / nDisable Demo ShowText on DialogBar IDM_SHOW_TXT ShowText On Dialogbar Demo / NShowText On Dialogbar

The string before / n will be displayed in the status bar as a command, and the portion after the / n will appear as a prompt of the toolbar button with the same ID in the Tooltip window.

Modify Dialog Bar: Add a input box and button to the Dialog Bar, the button has the same ID as IDM_SHOW_TXT with a menu item, which can use the mapping menu message to process the button message (of course, using different ID values ​​can also be used with ON_COMMAND) Map the button message on the Dialog Bar, but ClassWizard does not provide a way to map to the Dialog Bar, which can only be manually adding message mapping code). legend

Modifying toolbar: Add two buttons to the toolbar, IDM_CHECK and IDM_DISABLE and two menu items have the same ID value. legend

Add a message mapping and update command to three menu items using ClassWizard. legend

Modify the mainfrm.h file

// Add a member variable to record the check status of the CHECK button on the toolbar. Protected: BOOL M_FCHECK; / / Handmade Adding Status Bar Part Two For display time update command, and update commands for disabling / allowing input box // {{{{AFX_MSG (CMAINFRAME) AFX_MSG Int Oncreate (lpcreateStruct LPCreatestruct); AFX_MSG void onCheck (); afx_msg void OnUpdateCheck (CCmdUI * pCmdUI); afx_msg void OnDisable (); afx_msg void OnUpdateDisable (CCmdUI * pCmdUI); afx_msg void OnShowTxt (); afx_msg void OnUpdateShowTxt (CCmdUI * pCmdUI); //}} aFX_MSG / / The above part of the code AFX_MSG Void OnUpdateTime (CCMDUI * PCMDUI) generated by ClassWizard; // Display Time AFX_MSG Void OnUpdateInput (CCMDUI * PCMDUI); // Disable / Allow the input box to modify the mainfrm.cpp file

/ / Modify the status bar on each part ID # define ID_time 0x705 // As the second part iDStatic uint indeicators [] = {id_separetor, // status line indeicator id_separator, // is set to ID_SEPARATOR, after the status bar is created then modify}; // modify message mapping // {{AFX_MSG_MAP (CMainFrame) ON_WM_CREATE () ON_COMMAND (IDM_CHECK, onCheck) ON_UPDATE_COMMAND_UI (IDM_CHECK, OnUpdateCheck) ON_COMMAND (IDM_DISABLE, OnDisable) ON_UPDATE_COMMAND_UI (IDM_DISABLE, OnUpdateDisable) ON_COMMAND (IDM_SHOW_TXT, OnShowTxt ) ON_UPDATE_COMMAND_UI (IDM_SHOW_TXT, OnUpdateShowTxt) //}} AFX_MSG_MAP // more portions to automatically generate code ON_UPDATE_COMMAND_UI ClassWizard (ID_TIME, OnUpdateTime) display time ON_UPDATE_COMMAND_UI (IDC_INPUT_TEST, OnUpdateInput) // disable / enable input box // modify OnCreate function, resetting Status Bar 2 Id Value INT CMAINFRAME :: OnCreate (LPCReatestruct LPCreatestruct) {.... // By Wenyy Modify Status Board Part 2 Information M_WndStatusBar.SetPaneInfo (1, ID_TIME, SBPS_NORMAL, 60); // SET THE Width Return 0;} // Modify the mappled message processing function code void cMAINFRAME :: onCheck () {// changes and save status m_fcheck =! m_fcheck;} at the check button.

Void CMAINFRAME :: OnUpdateCheck (ccmdui * pcmdui) {// check button is set to check status PCMDUI-> setCheck (m_fcheck);}

The void cmainframe :: overdisable () {// disable button is pressed by AfxMessageBox ("You Press Disable Test");

Void CMAINFRAME :: onupdatedisable (ccmdui * pcmdui) {// According to the check status, it is determined according to the prohibition / allowed state pcmdui-> enable (m_fcheck);} void cMainframe :: OnShowtxt () {// get the in-box word on the Dialog Bar and Display CEDIT * PE = (CEDIT *) m_wnddlgbar.getdlgitem (IDC_INPUT_TEST); CSTRING SZO; PE-> getWindowText (SZO); AFXMESSAGEBOX (SZO);

Void CMAINFRAME: ONUPDATESHOWTXT (CCMDUI * PCMDUI) {// Dialog Bar On the CHECK State Determined itself / allowed status PCMDUI-> Enable (m_fcheck);

Void CMAINFRAME :: OnUpdateInput (ccmdui * pcmdui) {// Dialog bar on the input box Determine itself / allowed status PCMDUI-> enable (m_fcheck);} according to the check status

Void CMAINFRAME :: On DateTime (ccmdui * pcmdui) {// Depending on the status bar on the current time CTIME TIMECUR = CTIME:: getCurrentTime (); char sout [20]; sprintf (szout, "% 02D:% 02D) :% 02d ", timecur.gethour (), timecur.getminute (), timecur.getSecond (); pcmdui-> settext (szout);

Download Demonstration Code 17K

Copyright 怡 洋 http://www.vchelp.net/

4.e general window

From the MFC class feeding map provided by the VC, we can see the derived relationship between the window, the derived map, all the window classes are derived from CWND. All CWND members can be used in their derived classes. This section describes some common functions to everyone.

Change window status: BOOL EnableWindow (Bool Benable = true); You can set the disable / allowed state of the window. Bool iswindowenabled (); You can query the ban on the window / allowed state. BOOL ModifyStyle (DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0) / BOOL ModifyStyleEx (DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0); can modify the style of the window, without the need to call SetWindowLong BOOL IsWindowVisible () to check whether the window display. Bool ShowWindow; will change the display status of the window, ncmdshow can take the following value:

SW_HIDE Hide Window SW_MINIMIZE SW_SHOWMAXIMIMIMIZED Maximum Window SW_RESTORE Recovery Window SW_SHOW Display Window SW_SHOWMIMIMIZED Maximization Window

Change the window location: Void MoveWindow (LPCRect LPRECT, BOOL BREPAINT = true); You can move the window. Void getWindowRect (LPRECT LPRECT); the rectangular position of the window can be obtained. Bool isiconic (); You can detect if the window has been abducted icon. Bool SetWindowPos (Const Cwnd * PWndInsertAfter, int X, int y, int Cx, int CY, uint nflags); the z order of the window can be changed, and the window position can be moved.

Make the window fail, issue redrawing: void invalidate; make the entire window invalid, berase will determine if the window is redrawn. Void InvalidateRect (lpcRect LPRECT, BOOL BOOL BERASE = true) / Void Invalidatergn (CRGN * Prgn, Bool Berase = true); the specified rectangular / polygon area will be invalidated. Window Find: Static CWnd * Pascal FindWindow (LPCTSTR LPSZCLASSNAME, LPCTSTSTR LPSZWINDOWNAME); You can look up the window with the window name and window name. Any parameter is set to a NULL table arbitrarily matches the data represented by the parameter. Such as FindWindow ("MyWnd", NULL indicates all windows that look for class name myWnd. BOOL Ischild (Const CWND * PWND) Detection window is a child window. CWND * getParent () Get the parent window pointer. CWnd * getdlgitem (int NID) Get window pointers through the sub-window ID. INT getdlgctrlid () gets the window ID value. Static CWND * Pascal WindowFromPoint; Get a coordinates from the screen to get the window pointer containing the point. Static CWND * Pascal fromHandle (HWND HWND); constructs a CWND * pointer via HWND, but the pointer is deleted when it is idle, so it cannot be saved for later use.

Clock: uint setTimer (Uint NidEvent, Uint NELAPSE, VOID (Callback Export * LPFntiM) (HWND, UINT, UINT, DWORD)); You can create a clock, if the LPFNTIMER callback function is null, the window will receive a WM_TIMER message, and You can arrange the code BOOL KILLTIMER (INT NIDEVENT) in AFX_MSG Void Ontimer (uint nidEvent); delete a specified clock.

You can use the overload to add a virtual function of the message processing: AFX_MSG INT OnCreate (LPCReateStruct LPCreateStruct); the window is called AFX_MSG void onDestroy () when the window is being created; the window is called AFX_MSG Void OnGeTminMaxInfo (MinMaxInfo Far * LPMMI); you need to get When the window size is called, AFX_MSG VOID ONSIZE (INT NTYPE, INT CX, INT CY); the window is called AFX_MSG Void OnMove (INT X, INT Y); the window is called an AFX_MSG void onpaint (); window When you need to redraw, you can fill in the drawing code. For the view class, you don't need to overload onPaint. All draw code should make AFX_MSG Void onchar (uint nchar, uint nrepcnt, uint nflags) in OnDRAW; receiving the character input Call AFX_MSG VOID ONKEYDOWN / ONKEYUP (UINT NCHAR, UINT NREPCNT, UINT NFLAGS); the keyboard is called on / msg void onlbuttondown / onrbuttondown (uint nflags, cpoint point); the left / right button is pressed is called afx_msg void OnLButtonUp / OnRButtonUp (UINT nFlags, CPoint point); is called afx_msg void OnLButtonDblClk / OnRButtonDblClk the mouse left / right release (UINT nFlags, CPoint point); mouse left / right double-click is called afx_msg void OnMouseMove (UINT NFLAGS, CPOINT POINT; mouse is called to move when moving on the window Http://www.vchelp.net/

4.F How to use WM_NOTIFY

WM_NOTIF gets a lot of applications in Win32, and is also the basic message of CommControl with the appearance of CommControl. It can be said that all new features of CommControl are expressed by WM_Notify. At the same time, WM_NOTIFY also has a consistency to CommControl's operations.

The parameters in the WM_NOTIFY message are as follows: idctrl = (int) WPARAM; PNMH = (lpnmhdr) LPARAM; where lparam is one

Typedef struct tagnmhdr {hwnd hwndFrom; uint code;} nmHDR; structural pointer from the parameter of the message We can deal with the source of the message, but this information is not enough to divide the specific meaning of the message. So we need more data to get more information. The MS approach is to define another structure for each different use notification message, and in this structure contains Struct TagNMHDR, so you can get the data pointer as long as you do the type conversion. For example LVN_COLUMNCLICK message (to have the first mouse click ListCtrl list is notified), the structure; typedef struct tagNMLISTVIEW {NMHDR hdr; int iItem; int iSubItem; UINT uNewState; UINT uOldState; UINT uChanged; POINT ptAction; LPARAM lParam NmlistView, Far * lpnmlistView;

The most beginning of this structure contains Struct TagnmHDR, so more information is provided to process messages without loss of data and generating errors. In addition, we can perform a message mapping in an exact same manner through WM_NOTIFY, as seen in the previous chapter. Use the following form: ON_NOTIFY (WNOTIFYCODE, ID, Memberfxn). The processing function also has a unified prototype: AFX_MSG Void MemberFXN (NmHDR * pNOTIFYSTRUCT, LRESULT * Result); in the internal mapping of the MFC message map, PNMH-> Code (PNMH = (PNMH = (lpnmHDR LPARAM) Match, and then call the corresponding processing function.

Another point is to use WM_NOTIFY / ON_NOTIFY_REFLECT to handle some messages inside the window, thereby establishing reusable controls. You can refer to Build Reusable MFC Control Classes. I am also ready to translate this article when I am free.

Copyright 怡 洋 http://www.vchelp.net/

5.1 Editing dialog boxes using resource editor

The pop-up dialog in Windows Development is a commonly used input / output means, while editing dialogs can be saved in the resource file. Visual C provides dialog editing tools, using editing tools to easily add a variety of controls to dialogs, and using ClassWizard can easily generate new dialog classes and mapping messages.

First click on the resource list, you can select "Insert dialog box" in the pop-up menu, as shown in Figure 1. Then open the dialog for editing, you will see a control board on the screen, as shown in Figure 2. You can drag the controls you need to the dialog, or first select the area in the dialog box.

Next we generate an input box on the dialog, and a picture box for displaying icons. Then we right-click the generated control and select its properties, as shown in Figure 3. We can edit the properties of the control in the Properties dialog, and you also need to specify the control ID, as shown in Figure 4, if you select the property of the dialog, you can choose some properties of the dialog, including the font, appearance, whether there is a system menu, etc. Wait. Finally, we edit the properties of the picture control, as shown in Figure 5, we set the properties of the control to display the icon and specify an icon ID.

Next, we add some other controls, the final effect is shown in Figure 6. Press CTRL-T to test the dialog. In addition, there is also a useful feature in the dialog, that is, you can use the Tab key to move the input focus in each control. To achieve this, you need to set the property Tab STOP that you can accept for the control when you press the Tab button. TAB STOP, If a control is not intended to take advantage of this feature, you need to clear this property. Then select Tab ORDER from the menu "Layout" to determine the order of the focus movement, as shown in Figure 7. Use the mouse to click on this click control to replace the focus movement. Finally, Press CTRL-T for testing.

Finally, we need new classes for the dialog, ClassWizard can do most of our work for us, we only need to fill in several parameters. Double-click on the editing dialog, then the system will ask if you add a new dialog box, select Yes and enter the class name in the next dialog. ClassWizard will generate the needed header files and CPP files. Then include the corresponding header file in the place where you need to use, use Domodal () generation for the Mode dialog, use create () generation. The relevant code is as follows;

Void cmy51_s1view :: oncreatedlg () {// Generate a mod mode dialog ctestdlg * dlg = new ctestdlg; dlg-> create (idd_test_dlg); dlg-> showwindow;} void cmy51_s1view :: overdomodal () {// generation There is a pattern dialog (IRET = DLG.DOMODAL (); "DLG RETURN% D / N", IRET);

Download example. If you are debugging this program, you will find that the program will have memory leaks after exiting, because I didn't release the memory used by the Mode dialog, this problem will create a unparalleled dialog in the future section 5.3 Tell.

About the process of Enter and Escape keys when using the dialog box: Use the dialog box that you will find that when you press the Enter key or the ESCAPE button, you will exit the dialog, because the Enter key will cause cdialog :: onok () Call, and the Escape key causes CDIALOG :: OnCancel (). And these two calls will cause exit of the dialog. These two member functions in the MFC are virtual functions, so we need to overload, if we don't want to exit dialog, we can do anything in the function, if you need to check, you can add check code, then call The parent class is onok () or oncancel (). The relevant code is as follows;

Void ctestdlg :: onok () {AFXMessageBox ("You Select OK"); cdialog :: onok ();}

Void ctestdlg :: oncancel () {AFXMESSAGEBOX ("You choose Cancel"); cdialog :: oncancel ();

Copyright 怡 洋 http://www.vchelp.net/

5.2 Creating a Mode dialog

When you use the Mode dialog box, the call is called when the dialog is popped up, but is not immediately returned until the dialog is destroyed (please note that the message of other windows after the dialog is pop-up). So other windows cannot receive user input when using the dialog. The method of creating a mode dialog is to call CDIALOG :: Domodal (). The following code demonstrates this usage:

Cyourview :: onopendlg () {cyordlg DLG; int rt = DLG.DOMODAL ();

The return value of cdialog :: Domodal () is IDOK, IDCANCEL. Indicates that the operator selects "Confirm" or "Cancel" on the dialog. Since Domodal does not return before the dialog is destroyed, a local variable can be used to reference the object. The object after exiting the function is also destroyed. And for the Mode dialog box cannot be used, this 5.3 is created in the Unmatched Mode dialog in detail.

You need to determine your next action according to the return value of Domodal (), and get the return value is also a big reason for using the Mode dialog.

Using the Mode dialog requires some questions, such as generating a mode dialog box during some repeated event processing, such as a mode dialog box is generated in the timer, because the last dialog has not been exited The timer message will cause the next dialog box.

Similarly, in your dialog box, you can call CDIALOG :: Onok () or cdialog :: onokance () or cdialog :: oncancel () to return to IDOK or IDCANCEL, if you want to return other values, you need to call CDIALOG :: EndDialog (int NRESULT); where NRESULT will be used as the return value called by Domodal ().

The following code demonstrates how to use your own function to exit dialog box: Download example

void CMy52_s1View :: OnLButtonDown (UINT nFlags, CPoint point) {// create a dialog box and return value CView :: OnLButtonDown (nFlags, point); CTestDlg dlg; int iRet = dlg.DoModal (); CString szOut; szOut.Format ("Return Value% D", IRET); AFXMessageBox (Szout);} // Reserved Onok, oncancelvoid ctestdlg :: onok () {// Nothing} void ctestdlg :: oncancel () {// What is also No} // In the dialog box, the three button messages are mapped void ctestdlg :: Onexit1 () {cdialog :: onok ();} void ctestdlg :: Onexit2 () {cdialog :: oncancel ();} void ctestdlg (); :: OneXIT3 () {cdialog :: enddialog (0xff);} Due to the overok and oncancel, do not quit when pressing the Enter or the ESCAPE button in the dialog, only one of the three buttons Will return.

In addition, in the dialog box is generated, Bool CDialog :: OnInitDialog (), if you need to initialize the controls in front of the dialog box, you need to overload this function and fill in the relevant initialization code. With ClassWizard, you can easily generate some default code. First open ClassWizard, select the corresponding dialog class, select WM_INITDIALOG and double click in the message list, such as the figure, ClassWizard automatically generates the code, the code is as follows:

Bool ctestdlg :: OnNitDialog () {/ * first call the same name function * / cDialog :: oninitdialog (); / * Fill your initialization code * / return true;}

For the initialization of the controls in the dialog box, in 5.4 perform more detailed explanation in the dialog box.

Copyright 怡 洋 http://www.vchelp.net/

5.3 Creating a Mode Dialog

The Mode dialog box is different from the mode dialog box that can continue to receive user input after the other window is created, so there is a pop-up window similar to the Mode dialog. Create a modeless dialog box to call Bool CDialog :: Create (uint nidTemplate, CWnd * pParentWnd = null); then you need to call Bool CDialog :: ShowWindow (SW_SHOW); display, otherwise the Mode dialog will be invisible. The relevant code is as follows:

Void CyourView :: On Whumview: {/ * Assume IDD_test_dlg for the ID number * / ctestdlg * DLG = New Ctestdlg * DLG = New Ctestdlg; DLG-> Crete (IDD_TEST_DLG, NULL); DLG-> ShowWindows (SW_SHOW); / * Do not call DELETE DLG; * /}

In the above code we have newly generated a dialog object, and the object is not destroyed when exiting the function. Because if the object is destroyed (the window is destroyed when the object is destroyed), the dialog is still incorrect. Then this will put a question: When is it destroyed? There are two methods that I often use: destroy yourself when the dialog exits: In the dialog box, the ONOK is called with the oncancel to call the same name function of the parent class in the function, then call DESTROYWINDOW () to force the destruction window, map in the dialog WM_DESTROY message, call Delete this in the message processing function; forcibly delete its own object. The relevant code is as follows: void ctestdlg1 :: onok () {cdialog :: onok (); destroyWindow ();} void ctestdlg1 :: oncancel () {cdialog :: oncancel (); design; design; design; design; design;

Void ctestdlg1 :: ONDESTROY () {cdialog :: overdestroy (); afXMESSAGEBOX ("Call Delete this"; delete this;}

This method is to delete its own object when the window is destroyed. So you can call DESTROYWINDOW () at any time to achieve the role of completely destroying your own object. (DESTROYWINDOW () calls can cause the call of ONDSTROY () to send messages to the father window: First need to define a message to make a notification, then map WM_DESTROY message in the dialog box, in the message The call message send function in the processing function notifies other windows. Use the ON_MESSAGE mapping to process the function in the window to remove the dialog object in the message processing function. The relevant code is as follows: / * Change dialog information * / ctestdlg2 :: ctestdlg2 (cDial * pParent / * = null * /): cdialog (ctestdlg2 :: idd, pparent) {/ * m_pparent is a member variable, used for Save the pointer to the notification window, so the pointer cannot be a temporary pointer * / assert (pParent); m_pparent = pParent; // {{AFX_DATA_INIT (CTESTDLG2) // Note: The classwizard will address // Note: The classwizard will add member initialization here //}} AFX_DATA_INIT} Void ctestdlg2 :: onok () {cdialog :: onok (); destroyWindow ();

Void ctestdlg2 :: oncancel () {cdialog :: oncancel (); destroyWindow ();

Void ctestdlg2 :: ONDESTROY () {cdialog :: ONDESTROY (); / * Send a message to another window, send its own pointer as a parameter * / m_pparent-> PostMessage (WM_DELETE_DLG, (WPARAM);}

/ * Add message mapping in the message receiving window * // * Add function definition in the header file * / AFX_MSG long OnDeldlgMSG (WPARAM WP, LPARAM LP); / * Add Message Map Code * / ON_MESSAGE (WM_DELETE_DLG, ONDLGMSG) END_MESSAGE_MAP ) / * Implement message processing function * / long CMY53_S1View :: Ondeldlgmsg (WPARAM WP, LPARM LP) {delete (ctestdlg2 *) wp; return 0;} / * Create dialog * / void cmy53_s1view :: ontest2 () {ctestdlg2 * DLG = new ctestdlg2 (this); DLG-> Create (IDD_TEST_DLG_2); DLG-> ShowWindow (sw_show);} In this method we use messages to make notifications, using messages in the Window system to notify and pass data usage It is very much.

Another role of the same non-Mode dialog can also be used to reflect other windows in time when the user changes in the dialog box. The following code demonstrates the input of a paragraph in the dialog, and then updates it to the display area of ​​the view, the same also utilizes messages to notify and data delivery.

/ * Remove the data in the dialog box, send messages and data to other windows, send the data pointer as a parameter * / void ctestdlg2 :: oncomMBTN () {char Szout [30]; getdlgitemtext (IDC_OUT, SZOUT, 30); m_pparent-> sendMessage (wm_dlg_notify, (wparam) szout);

/ * In the message receiving window * // * mapping message processing function * / on_MESSAGE (WM_DLG_NOTIFY, ONDLGNOTIFYMSG)

/ * Draw a string m_szout * / void cmy53_s1view :: overdraw (CDC * PDC) {CMY53_S1DOC * PDOC = getDocument (); assert_valid (pdoc); // Todo: add draw code for native data here PDC-> Textout (0, 0, "Display String"); PDC-> TextOut (0, 20, m_szout);} / * Processing Notification Message, save information and update display * / long cmy53_s1view :: OndlGnotifyMSG (WPARAM WP, LPARAM LP) {M_szout = (char *) wp; invalidate (); return 0;}

In addition, this method of using messaging data is also as effective in communication between the mode dialog and other windows. Download this section example

Copyright 怡 洋 http://www.vchelp.net/

5.4 Message mapping in the dialog

The advantage of using the dialog is that the textwizard can map the messages generated by each control in the dialog, and the classwizrd can list the messages that can be used by various controls and automatically generate code. In this section, we explain how to map sub-window messages in the dialog and explain how to initialize the sub-windings in the dialog.

First we produce a good editor dialog box, as shown, controls, and use the ID number in the dialog box as follows: ID type IDC_RADIO_TEST_1 IDC_RADIO_TEST_2 round button round button IDC_BUTTON_TEST button IDC_CHECK_TEST check button IDC_TREE_TEST tree control IDC_LIST_CTRL List Ctrl IDC_TAB_CTRL Tab Ctrl IDC_LIST_TEST list box IDC_COMBO_TEST Combination Box IDC_EDIT_TEST Input Box First We need to initialize individual controls in the OnInitDialog () function of the dialog. Here we use CWND * GetdlgiteM (int NID) to get the child window pointer through the ID number. (Similar functions also have uint getdlgitemint (int NID, BOOL * LPTRANS = NULL, BOOL BSIGNED = true) Gets the number entered in the sub-window via the ID number, int GETDLGITEMTEXT (INT NID, CSTRING & RSTRING) Get the child window via the ID number Enter text). code show as below:

BOOL CMY54_S1DLG :: OnNitDialog () {cdialog :: OnItDialog (); / * Add initialization code * / // Initialization input box (CEDIT *) getDLGITEM (IDC_EDit_test)) -> setWindowText ("this is a edit box"; // Initialize list box clistbox * plistb = (clistbox *) getdlgitem (idc_list_test); PListB-> AddString ("item 1"); PListB-> AddString ("Item 2"); PListB-> AddString ("Item 3") ; // Initialization combination box CCOMBOBOX * PCB = (ccombox *) getdlgitem (IDC_COMBO_TEST); PCB-> AddString ("Item 1"); PCB-> AddString ("Item 2"); PCB-> AddString ("Item 3" ); // Initialize Tab Ctrl CTabctrl * PTAB = (CTabCtrl *) getdlgitem (IDC_TAB_TEST); PTAB-> INSERTITEM (0, "Tab Page1"); PTAB-> InsertItem (1, "Tab Page2"); PTAB-> INSERTITEM (2, "Tab Page3"); // Initialize ListCtrl ClistCtrl * PLIST = (CListCtrl *) getdlgitem (idc_list_ctrl); PLIST-> INSERTCOLUMN (0, "Column 1", LVCFMT_LEFT, 100); PLIST-> InsertItem (0, "Item 1"); PLIST-> INSERTITEM (1, "Item 2"); PLIST-> INSERTITEM (2, "ITEM 3"); // Initialize TreeCtrl CTreeCtrl * ptree = (ctreeCtrl *) getdlgitem (IDC_TREE_TEST); PTREE -> InsertItem ("Node1", 0); HtreeItem Hnode = Ptree-> InsertItem ("Node2", 0, 0); Ptree-> InsertItem ("Node2 -1 ", 0, 0, hnode); PTREE-> INSERTITEM (" Node2-2 ", 0, 0, Hnode); PTREE-> Expand (Hnode, TVE_EXPAND); Return True; // Return True UnsS you set the Focus to a control}

Next we need to use ClassWizard to map the messages generated by the control, open the ClassWizard dialog, select the ID of the relevant control, and the available messages are displayed in the list on the right. If we map the button's message, after the button ID (IDC_Button_Test), two messages will be seen, as shown, one is bn_clicked, one is bn_doubleclicked. After double-click BN_Clicked, enter a function name in the pop-up dialog, ClassWizard generates a message mapping that the button is pressed.

Then we look at the TCN_SELCHANGE message of TabCtrl, as shown, this message is sent when the current page of TabCtrl changes, so the message can be notified in time when the current page changes. Finally, we mapping the En_Change message of the input box, as shown, the message is sent after the text in the input box changes. The relevant code is as follows:

// message header file of the handler definition on afx_msg void OnButtonTest (); afx_msg void OnSelchangeTabTest (NMHDR * pNMHDR, LRESULT * pResult); afx_msg void OnChangeEditTest (); //}} AFX_MSG DECLARE_MESSAGE_MAP ()

// CPP message file mapping code ON_BN_CLICKED (IDC_BUTTON_TEST, OnButtonTest) ON_NOTIFY (TCN_SELCHANGE, IDC_TAB_TEST, OnSelchangeTabTest) ON_EN_CHANGE (IDC_EDIT_TEST, OnChangeEditTest) //}} AFX_MSG_MAPEND_MESSAGE_MAP ()

// message processing function void cmy54_s1dlg :: onbuttontest () {AFXMESSAGEBOX ("You Pressed A Button");}

Void CMY54_S1DLG :: OnSelchangeTabtest (nmHDR * pnmhdr, lresult * pResult) {trace ("tab select change / n"); * PRESULT = 0;}

Void CMY54_S1DLG :: ONCHANGEDITTEST () {trace ("edit_box text change / n");

Similar methods can be made for other controls to perform message mapping, download examples. Also if you are not familiar with the messages you can use for various controls, you can use the dialog box, then use ClassWizard to generate relevant code methods, you can also copy the code generated by the ClassWizard directly to other needs (no You said, I started learning like this :- This is also a small trick).

Copyright 怡 洋 http://www.vchelp.net/

5.5 Data exchange and data check in the dialog

The MFC provides two ways to perform data exchange and data check (Dialog Data Exchange / Dialog Data Validation), data exchange, and data checks are to associate a variable and a sub-window in the dialog box, then pass Call Bool Updatedata (Bool BsaveAndValidate = true) to indicate that MFC puts data in a variable into a sub-window or in a sub-window to a variable and perform legality check.

A sub-window can be associated with two types of variables when performing data exchange, one is a control (Control) object, such as the button sub-window can be associated with a CButton object, in which case you can pass directly The control sub-window does not need to use getDLGITEM (IDC_Control_ID) as in the previous section to get the window pointer; one is a content object, such as the input box can be associated with a CString object, or an UINT type variable is associated. In this case you can set it directly to the input content in the window.

The data check is legally checking the content when accessing content is associated with a sub-window and a content object. For example, when an input box is associated with a CSTRING object, you can set the longest of check CSTRING objects. / Minimum length, when entering the box and a UINT variable, you can set the maximum / minimum value of the UINT variable. After the Bool Updatedata (Bool BsaveAndValidate = true) is called, the legality check will be made automatically. If you cannot make a prompt by checking the MFC pop-up message box and returns false. Setting DDX / DDV in VC very simple in VC, ClassWizard can do all work for you, you only need to open ClassWizard and select Member Variables page, as shown, you can see all the sub-window IDs that can be associated, double click on one ID A dialog box that adds a variable will pop up, as shown, fill in the relevant information, press the OK button. Then select the variable you just added to the input box in the bottom of the check condition, as shown.

Let's take an example, the sub-window on the dialog is set, the ID and associated variables of each sub-window are as follows: ID associated variables the IDC_CHECK_TEST BOOL M_FCHECK Check box is selected by Idc_Radoi_Test_1 Int m_isel Currently selected Round button Index IDC_COMBO_TEST CSTRING M_SZCOMBO Multi-IdT_Test CString M_SzEdit_test CString M_SzEdit_test CString M_SzEdit_test CString M_SzEdit_test CString M_SzEdit_test CString M_SzEdit_test CString M_SzEdit Clistbox M_LbTest list box Object When ClassWizard automatically generates variable definitions and related code, in dialogue In the constructor of the box, the initial value of the variable can be set, and the Updatedata (FALSE) is called in Bool CDialog :: OnNitDialog (), the data in the variable is placed in the window. The relevant code is as follows:

// variables defined in the header file, ClassWizard automatically generated // Dialog Data // {{AFX_DATA (CMy55_s1Dlg) enum {IDD = IDD_MY55_S1_DIALOG}; CListBox m_lbTest; int m_iSel; CString m_szEdit; CString m_szCombo; BOOL m_fCheck; //}} AFX_DATA // Constructor Assignment CMY55_S1DLG :: CMY55_S1DLG (CWND * PParent / * = NULL * /): CDIALOG (CMY55_S1DLG :: IDD, PPARENT) {// {{AFX_DATA_INIT (CMY55_s1dlg) m_isisel = -1; m_szedit = _T (""); m_szcombo = _t (""); m_fcheck = false; //}} //classwizA_init "and check code void CMY55_S1DLG :: DODATAEXCHANGE (CDataExchange * pdx) {cdialog :: DoDataExchange (pDX); // {{AFX_DATA_MAP (CMy55_s1Dlg) DDX_Control (pDX, IDC_LIST_TEST, m_lbTest); DDX_Radio (pDX, IDC_RADIO_TEST_1, m_iSel); DDX_Text (pDX, IDC_EDIT_TEST, m_szEdit); DDV_MaxChars (pDX, m_szEdit, 5) ; DDX_CBString (pDX, IDC_COMBO_TEST, m_szCombo); DDX_Check (pDX, IDC_CHECK_TEST, m_fCheck); //}} AFX_DATA_MAP} // variables have been associated with excessive use of in OnInitDialog m_lbTestBOOL CMy55_s1Dlg :: OnInitDialog () {CDialog :: OnInitDialog () ; ... // TODO: Add Extra Initialization Here // Settings the Data M_Lbtest.Addstring ("String 1"); M _lbtest.addstring ("string 2"); m_lbtest.addstring ("string 3"); m_lbtest.addstring ("string 4"); return true; // return true unless} // Pair two A button message processing // Get the data vocated by Updatedata (TRUE) VOID CMY55_S1DLG :: OnGet () {if (Updatedata (TRUE)) {// Data legitory check, you can use data stored in the variable CString Szout; Stern .Format ("Radio =% D / nCheck IS% D / NEDIT INPUT IS% S / NCOMBOBOX INPUT IS% S / N", M_isel, m_fcheck, m_szedit, m_szcombo); AFXMessageBox (Szout);} // Else did not pass check } // Put the data into the window void CMY55_S1DLG: ONPUT () {m_szcombo = "onput test"; m_szcombo = "onput test"; Updatedata (false);}

In the above example we see that we can easily access data using DDX / DDV and Updatedata (BOOL), and can also perform legality checks at the same time. Download Example Code Copyright All Witry Http://www.vchelp.net/

5.6 Using Properties dialog

The Properties dialog is different from the normal dialog that it can provide multiple options pages at the same time, while each page can be edited by the resource editor in the way in which the dialog is edited, so that it brings convenience to the interface development. Also comply with the rules of the ordinary dialog box, so it is very convenient to learn. The property dialog is composed of two parts: a plurality of property pages (CPROPERTYPAGE) and Property dialogs (CPropertySheet).

First, you need to edit the properties page, select Insert in the Resource Editor, and select the Properties dialog box, you can insert a property page, as shown, or choose to insert a dialog box, then set the style to Child, Border settings For Thin, as shown. Then generate a new class according to this dialog resource, select CPROPERTYPAGE when selecting the base class, ClassWizard automatically generates the relevant code.

For CPropertySheet, you also need to generate new classes and all items that need to be added as a member variable. The property dialog is also divided into two models and non-mode. There are model properties dialogs to create, and Create () creation is created with Domodal (). The following code demonstrates how to create a property dialog box and add a property page:

// modify the constructor for the derived class CPropertySheet follows CSheet :: CSheet (): CPropertySheet ( "test sheet", NULL, 0) {m_page1.Construct (IDD_PAGE_1); m_page2.Construct (IDD_PAGE_2); AddPage (& m_page1); AddPage (& m_page2);} // Create a mode property dialog void cmy56_s1dlg :: onmod () {csheet sheet; sheet.domodal ();} // Create a modeless property dialog Void CMY56_S1DLG :: OnU () {csheet * Sheet = new csheet; Sheet-> Create ();

For the Properties dialog, you can use some of the following member functions:

CPROPERTYPAGE * CPROPERTYSHEET :: getActivePage () gets a pointer to the current activity page. Bool CpropertySheet :: SetActivePage (int NPAGE) is used to set the current activity page. INT CPROPERTYSHEET :: getPageCount () is used to get the total number of current pages. Void CpropertySheet :: RemovePage (int NPAGE) Used to delete a page. For the attribute page, it will mainly serve some functions to achieve control: void cpropertypage :: onok () Press the "OK" button on the Properties dialog and is called void cpropertypage :: oncancel () in the Properties dialog Press the "Cancel" button after pressing the "Cancel": ONApply () After pressing the "Application" button on the Properties dialog, you call Void CpropertyPage :: SetModified (Bool BChanged = true) Setting the data on the current page is modified Tag, this call can make the "Apply" button to allow. In addition, using the Properties dialog box you can generate the Wizard dialog, the wizard dialog also has multiple property pages, but only one page is displayed, and the button displayed on the dialog is "Previous", "Next" / "complete ", The Wizard dialog box will display all the pages in the order of your added page. You need to call Void CpropertySheet :: setWizardMode () before the Display Properties dialog box :: setWizardMode (). Using the Wizard dialog, you need to overload the Bool CPROPAGE :: ONSetActive () of the property page and call Void CpropertySheet :: SetWizardButtons (DWORD DWFLAGS) to set the button displayed on the Wizard dialog. DWFLAGS's value of the value of the following value: PSWIZB_BACK Display "Previous" button PSWIZB_NEXT Display "Next" button PSWIZB_FINISH Display "Finish" PSWIZB_DISABLEDFINISH Disabled "Complete" button Void CpropertySheet :: setWizardButtons (DWORD DWFLAGS) ) Can also be called elsewhere, for example, when the last page is displayed, the prohibited "completed" button is displayed, and the "Complete" button is displayed after completing some operations. When using the Wizard dialog, you can reach the control by overloading some functions:

Void CpropertyPage :: OnWizardback () Press the "Previous" button. Returns 0 indicates that the system determines that the page that needs to be displayed, -1 indicates that the page conversion is disabled, and if you want to display a specific page, you need to return the ID number of the page. Void CPropertyPage :: OnonWizardNext () Press the "Next" button. The return value meaning is the same as Void CPropertyPage :: OnWizardback (). Void CpropertyPage :: OnWizardFinish () Press the "Finish" button. Returns false means that it is not allowed, otherwise the True Wizard dialog will be ended. The Domodal () return value in the wizard dialog is ID_WIZFINISH or IDCANCEL. The following code demonstrates how to create and use the wizard dialog: // Create a mode wizard dialog void cmy56_s1dlg :: onwiz () {csheet sheet; sheet.SetWizardMode (); int rt = sheet.domodal (); // Return ID_WIZFINISH or IDCANCEL} // overload BOOL CPropertyPage :: OnSetActive () to control the buttons displayed BOOL CPage1 :: OnSetActive () {((CPropertySheet *) GetParent ()) -> SetWizardButtons (PSWIZB_BACK | PSWIZB_NEXT); return CPropertyPage :: OnsetActive ();} BOOL CPAGE2 :: OnseTactive () {(CPROPERTYET *) getParent ()) -> setWizardButtons (pswizb_back | pswizb_finish); return cpropertyPage :: onsetActive ();} Download this section example.

Copyright 怡 洋 http://www.vchelp.net/

5.7 Using General Dialogs

Some general dialogs are provided in the Windows system such as the file selection dialog, as shown in the figure, the color selection dialog is as shown in the figure, the font selection dialog is as shown. CFILEDIALOG, CCOLORDIALOG, CFONTDIALOG are used in MFC. Generally speaking, you don't need to derive new classes, because base classes have provided common functions. And after you create and wait for the dialog, you can get the options in the dialog box through the member function.

Use CFileDialog file selection dialog box: a first object and configured to provide the appropriate parameters as constructor function prototype: CFileDialog :: CFileDialog (BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWND * PPARENTWND = NULL); the parameters are as follows:

BopenfileDialog Displays the open dialog for TRUE, which displays the save dialog file dialog for False. LPSZDefext Specifies the default file extension. LPSZFileName Specifies the default file name. DWFlags indicates some specific styles. LPSZFilter is the most important parameter that indicates that the file type and the corresponding extension are available. Parameter formats such as "Chart files (* .xlc) | * .xlc | Worksheet files (* .xls) | * .xls | data files (* .xlc; *. Xls) | * .xlc; * .xls | all FILES (*. *) | *. * || "; File Type Description and Extension Demanitions | Separation, the extension of the same type file can be used; split, each file type | Separate, end | | Indicate. PParentWnd is a parent window pointer. The creation file dialog can use Domodal (), after returning, you can use the following function to get the user selection: cstring cfiledialog :: getPathName () Get full file name, including directory name and extension, such as: c: /test/test1.txt CString cfiledialog :: getFileName () Get full file name, including extensions such as: test1.txt cstring cfiledialog :: getExtName () Get full file extensions, such as: txt cstring cfiledialog :: getFileTitle () Get full file name Not including directory name and extension, such as: test1 position cfiledialog :: getStartPosition () Get the first file location for the case where multiple files are selected. CString CFiledialog :: GetNextPathname (Position & Pos) Get the next file location for the case where multiple files is selected and return to the current file name. But you must have called Position CfileDialog :: getStartPosition () to get the original position variable. CCOLORDIALOG color selection dialog: First constructed an object by ccolordialog :: ccolordialog (ColorRef Clrinit = 0, DWORD * PPARETWND = NULL), where CLRINIT is initial colors. Call the colorRef ccolorDialog :: getColor () get the color value selected by calling ColorRef ccolordialog :: getColor () after returning.

CFontDialog font selection using the dialog box: First, construct an object and provide the appropriate parameters as constructor function prototype: CFontDialog :: CFontDialog (LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC * pdcPrinter = NULL, CWnd * pParentWnd = NULL); Constructs an object, where the parameter LPLFINITIAL points to a logfong structure (this structure is described with respect to 2.2 Output text in the window), if the parameter is set to NULL means that the initial font is not set. PDCPrinter points to a DC object representing the printer device environment. If the parameter is set, the selected font is used for the printer. PParentWnd is used to specify the parent window. By calling the Domodal () creation dialog, you can get the user selection by calling the following functions:

Void cfontialog :: getCurrentFont (LPLogfont LPLF); used to get the properties of the selected font. This function has a parameter that is a pointer to the LogFont structure, and the function writes the various properties of the selected font to this LogFont structure. CSTRING CFONTDIALOG :: getfacename () get the name of the selected font. INT cfontdialog :: getSize () Get the size of the selected font (in 10 pixels). ColorRef cfontialog :: getColor () gets the color of the selected font. Bool CFONTDIALOG :: IsstrikeOut () BOOL CFONTDIALOG :: Isunderline () BOOL CFONTDIALOG :: Isbold () BOOL CFONTDIALOG :: Isbold () BOOL CFONTDIALOG :: isbold () BOOL CFONTDIALOG :: isbold () BOOL CFONTDIALOG :: isbold () BOOL CFONTDIALOG :: ISITALIC () gets the other attribute of the selected font, whether there is a delete line, whether there is a loop, whether it is a bold, Whether it is a bevel. Copyright 怡 洋 http://www.vchelp.net/

5.8 Establishing a dialog-based application

I think beginners use the application based on dialog boxes is a better choice, as this can be taken away from some development interfaces, and can also use ClassWizard to add message mapping.

The VC provides a feature that generates "dialog-based application". You need to select the first step in using AppWizard, "Dialog Based Application", as shown. The VC generates code containing the application derived class and dialog box. You can see the following code in the initInstance () member function of the application class:

BOOL CMy58_s1App :: InitInstance () {CMy58_s1Dlg 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 by Dialog IS // DISSED with CANCEL}

Return false;}

This is a model dialog and creation it, and then exits directly after returning after the dialog returns. In design, you can design the interface by editing dialog box, then handle the customer's input via the ClassWizard map message, because this section has been repeated due to the previous section.

Applications that are also based on dialogs can also be used as an interface using the Properties dialog, or by using the derived general dialog box as an interface.

Tip: When you use the Mode dialog, the most beginning is unable to hide the window, but only after the dialog is displayed, then hide the window, so this will cause the screen to flash. A solution is to use a modeless dialog box, and the mode-free dialog is hidden after being created until you call ShowWindow (SW_SHOW). The relevant code is as follows:

Bool CMY58_S1App :: InitInstance () {// must be newly generated, not using local variables CMY58_S1DLG * PDLG = new cmy58_s1dlg; m_pmainwnd = PDLG; PDLG-> Create (); return true;}

Copyright 怡 洋 http://www.vchelp.net/

5.9 Using the dialog as a child window

Using dialogs as a sub-window is a very common technology, which makes the interface design simplifies and modifies easier.

Simplely said that this technology is to create a non-mode dialog and indicate the Child style and boundless box when editing dialog resources, as shown in the figure. Next, use the derived class that produces a CDIALOG, and performs related message mappings. When creating a child window is required using the following code: int CMy59_s1View :: OnCreate (LPCREATESTRUCT lpCreateStruct) {if (CView :: OnCreate (lpCreateStruct) == -1) return -1; // Create the child window m_dlgChild.Create (IDD_CHILD_DLG, THIS); // Reposition m_dlgchild.moveWindow (0, 0, 400, 200); // Display window m_dlgchild.showwindow (sw_show); return 0;}

In addition, a similar technology is to use the CFormView derived class as a sub-window, and also need to indicate the Child style and boundless box when editing dialog resources. Then use ClassWizard to generate derived classes based on CFormView, but because the member functions of the class are protected, the resulting header file is required to modify the resulting header: Class Ctestform: public cFormView {// will constructor and configuration The analytical function is changed to a common function public: ctestform (); Virtual ~ ctestform (); declare_dyncreate (ctestform) ...}

The code about the creation sub-window is as follows: int CMY59_S1VIEW :: oncreate (lpcreatestruct lpcreateStruct) {if (cview :: oncreate (lpcreateStruct) == -1) Return -1; // For the CFormView derived class must be newly generated and not using members Object m_pformchild = new ctestform; // Since the member of CFormView is protected, the pointer must be forced to convert CWND * PWND = m_pformchild; PWnd-> Create (NULL, NULL, WS_CHILD | WS_VISIBLE, CRECT (0, 210, 400, 400), this, 1001, NULL); RETURN 0;

Finally, you will see the window interface of the figure, the above dialog box window and the FormView sub-window below can be pre-edited in advance, download code.

Tip: For the CFormView derived class, the object must be newly generated and the member object cannot be used because there is a code in CView's OnDestroy (): delete this; So the result of the member object will cause the object's second deletion to cause an exception.

Copyright 怡 洋 http://www.vchelp.net/

6.1 WINSOCK Introduction

Windows Under Network Programming - Windows Sockets is a widely used, open, supported network programming interface, which supports multiple protocols under WINDOWS. From version 1.0 from 1995 to version 2.0.8, it has become a factual standard for Windows network programming under the full support of Intel, Microsoft, Sun, SGI, Informix, Novell, etc.

The Windows Sockets specification defines a web programming interface for MicoSoft Windows in the popular Socket interface popular in U.c. Berkeley University BSD UNIX. It not only contains the library function of the Berkeley socket style that people are familiar with; also includes a set of extended library functions for Windows so that programmers can make programmers to program with Windows messaging mechanisms. The Windows Sockets specification is intended to provide a simple API to the application developer and let all network software vendors comply with. In addition, on the basis of a specific version Windows, Windows Sockets also defines a binary interface (ABI) to ensure that the application of the Windows Sockets API can work in accordance with the Windows Sockets protocol of Windows Sockets protocols. . Therefore, this specification defines a set of library functions that the application developer can use and the network software vendor can implement. Comply with this web software of this Windows Sockets, we call Windows Sockets compatible, and Windows Sockets-compatible providers, we call Windows Sockets providers. A network software vendor must implement the Windows Sockets specification percent to achieve Windows Sockets compatibility. Any application that can be compatible with Windows Sockets is considered to have a Windows Sockets interface. We call this application for the Windows Sockets application. The Windows Sockets specification defines and records how to use the API and the Internet protocol (IPS, usually we refer to TCP / IP), especially pointed out that all Windows Sockets implementation supports juncture interfaces and data sets. The program calls the API of Windows Sockets to implement communication between each other. Windows Sockets uses the next network communication protocol function and operating system call to implement actual communication work. The relationship between them is the basis of the figure, and a socket. A socket is one end of the communication. On this end you can find a name corresponding to it. A socket that is being used has its type and related processes. The socket exists in the communication domain. The communication domain is an abstract concept introduced to handle the general thread through the socket communication. The socket is usually exchanged with sockets in the same domain (data exchange may also pass the boundaries of the domain, but at this time you must perform some explanation). The Windows Sockets specification supports a single communication domain, which is an Internet domain. Various processes use this domain to communicate with an Internet protocol between each other (Windows Sockets 1.1 or more support for other domains, such as Windows Sockets 2). The socket can be classified according to the communication nature; this property is visible to the user. Applications generally communicate only in the sockets of the same class. However, as long as the underlying communication protocol is allowed, different types of sockets can also be communicated. The user can use two sockets, namely junction interfaces, and data sets. The junction interface provides two-way, orderly, no duplicate data stream services. The data setup interface supports the two-way data stream, but it is not guaranteed to be reliable, orderly, and no repetition. That is, a process from receiving information from a data setup interface is possible to find that the information is repeated, or the order in which it is issued. An important feature of the data settlement interface is that it retains the record boundary. For this feature, the data settlement interface uses a model that is very similar to now many package switched networks (such as Ethernet).

An example of the most commonly used application when establishing a distributed application is a client / server model. In this program, the client application requests services to the server program. This approach implies asymmetry when establishing inter-client communication. The client / server model requires a set of conventions convention consensus consensus to clients and servers to ensure that the service can be supplied (or accepted). This set of conventions contain a set of protocols. It must be implemented in both the communication. Depending on the actual situation, the agreement may be symmetrical or asymmetric. In the symmetrical protocol, each party may play a master from the role; in the asymmetric protocol, one party is not changed to be a host, and the other is the slave. An example of a symmetrical protocol is a Telnet for terminal simulation in the Internet. And an example of an asymmetric agreement is an FTP in the Internet. Regardless of the specific protocol is symmetrical or asymmetric, there must be "customer processes" and "service process" when the service is provided. A service program is usually a well-known address to listen to the service request, that is, the service process has been in a sleep state until a customer puts a connection request for the address of this service. At this moment, the service program is "awakened" and provides customers with services - the appropriate response to the client's request. This request / corresponding process can be represented by a simplicity. Although connection-based services are criteria for designing client / server applications, some services are also available through data sets. The data packet interface can be used to send a broadcast packet to a network supported by many systems. To implement this function, the network itself must support broadcast functions because system software does not provide any simulation of broadcast functionality. Broadcasting information will cause a load to the network because they require each host on the network to serve them, so the ability to send broadcast packets is limited to the sockets that are explicitly marked allowed broadcasts. Broadcasting is usually used for two reasons: 1. An application wants to find a resource in the local network, and the application has no prior knowledge of the address of the resource. 2. Some important functions, such as routing requirements to send their information to all neighters that can be found. The destination address of the broadcast information depends on this information broadcast on the network. A shorthand address is supported in the Internet domain for broadcast -inaddr_broadcast. Since the use of broadcasts must be bundled with a data settlement interface, all received broadcast messages have the sender's address and port.

The byte order of the Intel processor is consistent with the byte order of the DEC VAX processor. Therefore, it is different from the 68000 processor and the order of the Internet, so the user should be particularly careful to ensure the correct order. Any IP address and port number from the Windows Sockets function to the IP address and port number and the IP address and port number of the Windows Sockets function are organized according to the network sequence, which also includes the IP address domain and port in the data type of the SockAddr_in structure. Domain (but excluding SIN_FAMILY). Considering an application usually uses ports corresponding to the Time service to connect to the server, the server provides a mechanism to notify the user to use another port. Therefore, the port number returned by the GetServByname () function is already in the network order, and can be used directly to form an address without the need for conversion. However, if the user enters a number, and specifies the use of this port number, the application must convert it from the host sequence into a network order before using it to create an address (using the htons () function). Accordingly, if the application wants to display port numbers contained in an address (eg, from the getPeerName () function), this port number must be converted from the network to the host sequence before being displayed (using NTOHS. )function). Since the byte order of the Intel processor and Internet is different, the above conversion is unavoidable, the application's writer should use the standard conversion function as part of the Windows Sockets API, instead of using its own conversion function code. Because the future Windows Sockets implementation is possible to run on the host byte order and network byte sequence. Therefore, only applications using standard conversion functions are portable. In the MFC, MS provides the corresponding class CasyncSocket and CSocket, CasyncSocket provides a socket package feature based on asynchronous communication, and CSocket is derived from CasyncSocket, providing a higher level of functionality, such as sending and receiving sockets. The data and a file object (csocketfile) are associated, and through the read and write files to send and receive the purpose of sending and receiving data, the communication provided by the CSocket is synchronous communication, and the data does not return before or not sent. In addition, the MFC developers can not consider the network byte order and more communication details are ignored.

There are several parameters in a network communication / connection to be set: Local IP Address - Local Port number - the other party port number - the other party IP address. The two parts of the left are called a semi-associated, and it is called a full relationship when it is established with the two parts of the right. You can exchange data two-way on this fully-associated socket. If it is a connectionless communication, only one semi-association is required, indicating the other half of the parameters when sending and receiving, so that the connectionless communication can be sent to the specified port of the other host. In addition, whether there is no connection or connectionless communication, there is no need for both port numbers.

Mark by indicating lEvent included in the creation of CAsyncSocket object by calling BOOL CAsyncSocket :: Create (FD_CLOSE, LPCTSTR lpszSocketAddress = NULL UINT nSocketPort = 0, int nSocketType = SOCK_STREAM, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | | FD_CONNECT) To determine events that require asynchronous processing, do not need to wait after the correlation function call, the function will return immediately, then return the event notification after completing the task, and utilize the following member functions to handle various Network Event: Marking Events The function fd_read is a VOID OnReceive (int NERRORCODE) when data arrives; fd_write has data transmission to generate VOID ONSEND (INT NERRORCODE); fd_oob happens to Take Takes Take data, void onoutofbanddata (int NerrorCode) FD_ACCEPT acts as the server wait for the connection to successfully occurs successfully, fd_connect is a void onconnect (int NerrorCode) when the client connection is successful; fd_close socket occurs when Void onclose (int NERRORCODE); we see the overload There is a parameter NERRORCODE in the function, which is normal to complete, and non-zero means an error. You can get the error value via Int CasyncSocket :: getLastError (). Let's take a look at some of the features provided by the interface class, which we can easily create network connections and send data.

BOOL CAsyncSocket :: Create (UINT nSocketPort = 0, int nSocketType = SOCK_STREAM, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, LPCTSTR lpszSocketAddress = NULL); used to create a local socket, which is used nSocketPort The port number is zero means that the system is automatically selected, which is usually used in the client. NSocketType is used by the protocol, Sock_Stream indicates the use of a connectionful service, and Sock_DGRAM indicates that the connectionless datagram is used. LPSZSocketAddress is a local IP address, which can be used to represent 10.1.1.3. Bool CasyncSocket :: Bind (uint nsocketport, lpctstr lpszsocketaddress = NULL) Generates a network semi-association as a wait connection, or generating a network semi-association when using the UDP protocol. Bool CasyncSocket :: Listen (int nConnectionbackLog = 5) When the number of connections that can be accepted simultaneously when the sector is waiting, be careful not to receive a total of connections that can be accepted. Bool CasyncSocket :: Accept (CasyncSocket & ronnectedSocket, SockAddr * LPSOCKADDR = NULL, INT * LPSOCKADDRLEN = NULL) As the waiting connection to build, the connection will be created when the connection creation is created, the interface will be used Communication. Bool CasyncSocket :: Connect (LPCTSTSTR LPSZHOSTADDRESS, UINT NHOSTPORT); as a connection to initiate a connection to the waiting connection, you need to indicate the other party's IP address and port number. Void CasyncSocket :: Close (); Close the socket. INT CasyncSocket :: Send (const void * lpbuf, int NBUFLEN, INT NFLAGS = 0) int CasyncSocket :: Receive (void * lpbuf, int nbuffle, int nflags = 0); send and receive data after establishing a connection, NFLAGS is tagged Bit, both parties need to indicate the same tag. int CAsyncSocket :: SendTo (const void * lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress = NULL, int nFlags = 0) int CAsyncSocket :: ReceiveFrom (void * lpBuf, int nBufLen, CString & rSocketAddress, UINT & rSocketPort, int nFlags = 0 ); For the transmission and reception of data without connection communication, you need to indicate the IP address of the other party and the port number, NFLAGS is marked, and the two parties need to indicate the same tag. We can see that most functions returns a boolean value indicating whether it is successful. If an error occurs, you can get an error value via Int CasyncSocket :: getLastError ().

Since CSocket is derived from CAsyncSocket so all functions have CAsyncSocket, in addition you can BOOL CSocket :: Create (UINT nSocketPort = 0, int nSocketType = SOCK_STREAM, LPCTSTR lpszSocketAddress = NULL) to create a socket, the socket so that there is no way to create asynchronous Handling events, all calls must be returned after completion. In the above introduction, we see that the sockets provided by the MFC have masked the details, we only need to do very little work, you can develop software that uses the network to communicate.

Copyright 怡 洋 http://www.vchelp.net/

6.2 Using Winsock for unconnected communication

Winsock provides support for the UDP (User Dataset Protocol). We can send data to the host of the specified IP address via the UDP protocol, and can also receive data from the host of the specified IP address, the transmission and reception are in the same position. Secondary points. Use the CSocket to manipulate the connectionless data to send very simple, first generate a local set interface (need to specify the SOCK_DGRAM tag), then use int CasyncSocket :: Sendto (const void * lpbuf, int nbufflen, uint nhostport, lpctstr lpszhostaddress = null, int nflags = 0) Send data, int CasyncSocket :: ReceiveFrom (Void * LPBUF, INT NBUFLEN, CSTRING & RSocketAddress, Uint & RSocketport, int NFLAGS = 0) receives data. Function call sequence is shown.

The use of UDP protocols can be sent and received can be two-way, that is, any host can send and receive data. However, the UDP protocol is unconnected, so the transmitted data is not necessarily received, and the order in which the received sequence may be inconsistent with the transmission order. Below is the relevant code:

/ * Send data to the receiver port 6801 on port 6800 * /// send codes: BOOL CMY62_S1_Clientdlg :: OnItDialog () {cdialog :: OnInitdialog ();

// Create a local set M_SOCKSEND.CREATE (6800, SOCK_DGRAM, NULL); // Bind the local socket m_socksend.bind (6800, "127.0.0.1"); // Create a timer timing Send setTimer (1,3000 , Null); ...} void CMY62_S1_Clientdlg :: Ontimer (uint nidevent) {static IIndex = 0; char szsend [20]; sprintf (szsend, "% 010d", IIndex ); // Send UDP data int = m_socksend . SENDTO (SZSEND, 10, 6801, "127.0.0.1", 0); Trace ("Sent% D Byte / N", ISEND); ...}

// Receive Code Bool CMY62_S1_SERVERDLG :: OnItDialog () {cdialog :: OnInitdialog ();

// Create a local set of interface M_SockRecv.create (6801, SOCK_DGRAM, "127.0.0.1"); // Bind the local set of interface M_SockRecv.bind (6801, "127.0.0.1"); // Create a timer timing read Settimer (1,3000, null); ...} void cmy62_s1_serverdlg :: ONTIMER (uint nidEvent) {char szrecv [20]; cstract szip ("127.0.0.1"); uint uport = 6800; // Receive UDP Data INT IRECV = m_sockrecv.receiveFrom (SzRecv, 10, Szip, UPORT, 0); Trace ("ReceiveD% D Byte / N", IRECV); ...} / * The receiver reads data synchronously, so no reading The data function call will not return * / download example code, 62_s1_client project is the sender, 62_s1_server engineering is the recipient.

Copyright 怡 洋 http://www.vchelp.net/

6.3 Using Winsock communication with connections

Winsock provides support for TCP (Transfer Control Protocol). We can establish the host with the host of the specified IP address through the TCP protocol, and use the established connection to exchange data. Manipulating the connection data exchange with CSocket is simple, but in communication with the connection, you must have a connection request for the server's role waiting for the other party (customer party), so the server side needs to establish a listener interface, then in this set of interfaces Wait for a connection. A new socket is generated after the connection is established. The client can only create a connection after creating a set of connectors after creating a socket. For communication, whether orientation is, whether the transmission or sequence of transmitting and reception is guaranteed. The order of the function calls in both parties are shown.

The following code demonstrates how to establish a connection and send / receive data:

/ * The server is waiting for the connection on port 6802, and closes the listening socket after the connection is established. The client direction server port 6802 initiates a connection request * / BOOL CMY63_S1_SERVERDLG :: OnItDialog () {cDialog :: onInitdialog ();

CSocket SockListen; // Create a local set of interface SockListenTen.create (6802, sock_stream, "127.0.0.1"); // Binding parameters SockListenTen.bind (6802, "127.0.0.1"); socklisten.listen (5); / / Wait for the connection request, m_socksend is a member variable, used to communicate socklisten.accept (m_socksend); // Close the listener interface SockListenTen.Close (); // Start the timer, scheduled to send data setTimer (1,3000, null); .. , 10, 0); ...} BOOL CMY63_S1_Clientdlg :: OnNInitdialog () {cdialog :: OnNitdialog (); // Create a local set of interface m_sockrecv.create (); // initiator connection request BOOL FC = m_sockrecv.connect (" 127.0.0.1 ", 6802); Trace (" Connect IS% S / N ", (FC)?" OK ":" Error "); // Start Timer, Timer Receive Data SetTimer (1,3000, NULL); .. IRECV); if (IRECV> = 0) {szRecv [IRECV] = '/ 0'; m_szrecv = szrecv; Updatedata (false);} ...} Download example code, 63_s1_client project is customer, 63_s1_server engineering is server side.

转载请注明原文地址:https://www.9cbs.com/read-76764.html

New Post(0)