1. How to create a DLL in C Builder 2. Save information in Win.ini with C Bulider 3. How to detect hardware 4.c Builder in C Builder Responsive Message and Custom Message 5. Developed with C Builder Animation DLL 6. Making a screen saver 7.TCP / IP header format 8.udp 9. Judging Windows Desktop and other directory 10 Create a digital signature 11 with C Builder 11 Method 12 with Enter to control focus switching Intercepting Windows Message 13. Using the COMMATEXT 14. The program is displayed first when the program begins to display the information box 15. How to get the command line parameter of the program? 16. How to monitor clipboard 17. How to use OnIdle event 18. Write a serial asynchronous communication program 19.c Builder Non-visual components with C Builder 20. Establish Database VCL Using Database VCL with C Builder 21. C Builder Create an Internet-based point-to-point chat 22. Get the application icon with C Builder 23.big5 to GB conversion technology 24.c Builder allows your taskbar map to move 25.Tform 26. Create with BCB in Windows desktop Shortcut 27. Read and write reading magnetic zone 28.I / O port 29. Detect the mouse position 30. Make Win32 application jump into the system zero layer 31. How to get MEMO row and column 32. Use sockets 33.Windows95 How to hide the app under / 98 Do not let it appear in the CTRL-ALT-DEL dialog? 34. How to hide the application's task bar icon 35. Write your own ping.exe program 36. Develop a service 37 under Winnt with C Builder. How to automatically turn off Windows Screensaver 38 in C Builder 38. Show / Hide Task Bar Icon 39. Mailbox monitor 40.c building make a alarm 41. Instructions for dial-up Internet IP addresses 42. Write the TRAY program with C Builder 43. How to use code to minimize or restore programs 44. Making the main window display Copyright window 45. Judging whether it has been connected to the Internet 46. Get the login username 47. Hide Desktop icon 48. Run when the program starts 49. Call 50. Simulate keyboard button 51. Let the title bar flash 52. Start screen protection 53 Day Month Day Tissue 54. Keyboard Event 55. Hidden Task Ben 56. Prohibit Shutdown 57. How to start programs in minimization mode 58. After adding a line in MEMO, how to make the last line to display 59. How to set the wallpaper method? Creating a DLL in C Builder has attracted a lot of Delphi, VC, and VB programmers to its arms, a large number of C, C programmers since the C Builder, from the romantic Valentine's Day last year, have a large number of C, C programmers: finally have C visualization Tools, the same, from BC, Delphi to C Builder. Dynamic Link Library (DLL) is a programming method that is often encountered by Windows. Here I introduce how to create how to use DLL and some tips in BCB (C Builder). First, create: Use BCB File | New to create a new DLL project and save file BCB to generate a DLL program frame.
1. The DLLLENTRYPOINT function is an inlet method. If the user is called when the DLL is initialized or logged out, it is used to write to the DLL initializer and uninstaller; parameter: HinST is used to indicate the base address of the DLL; Reason is used to indicate the DLL The call mode is used to distinguish between multi-thread single thread pairs of DLL, create, uninstall DLL; 2. Add your own DLL procedure to create, functions; 3. Dllimport described with outlet; Example procedures are as follows: #include #pragma hdrstop extern grind fine __ declspec (dllexport) int test (); int WINAPI DllEntryPoint (HINSTANCE hinst, unsigned long reason, void *) {return 1;} int test () {? Return 3;} Note: Dynamic Link Library Calling Process, Different CALL methods __cdecl, __pascal, __fastcall, __stcall, __fastcall, __sdcall, BCB, __cdcl, The declaration method is: EXTERN 揅? __ decspec (dllexport) int __stdcall test (); For the process, the function is also changed to: int __stdcall test () 2, using DLLs There are two ways to use DLL in BCB: 1. Use a static call to first add an input interface library (Import Library), open the engineering project, open the project list, use the BCB View | Project Manager to open the project list (* .lib) to the project. Second, add an interface declaration in the header file. The routine is as follows: // deflude file extern 揅? __ declspec (dllimport) int __cdecl test (); // use function in main program Int i; i = test (); Note: (1) Dynamic Link Library calling process, When the function is moderate, the CALL is not written as __cdecl, and other needs declaration. (2) The DLL created by BCB has a corresponding input interface library (Import library), if there is only DLL without the library, the BCB's IMPLIB tool can be generated: IMPLIB XXX.LIB XXX.DLL; additional: Tlib XXX.LIB, XXX .lst produces a list of internal functions of the DLL, many Windows unless otherwise discovered by this method. 2. Dynamic Calling Dynamic Call Method To use loadLibrary () and getProcAddress () in the Windows API to tune the DLL library, pointing to the function location in the library, which is more common. The routines are as follows: hinstance dd; int _stdcall (* ddd) (void); DD = loadingLibrary (搙 xx.dll ?; ddd = getProcaddress (DD, 搕 EST ?; caption = INTOSTR (DDD ()); freeelibrary (dd) ; 3, Note: When you create a DLL, you should pay attention to set the Project Options. Packages Tags: Remove the Builder With Runtime Packages Check box.
Linker Tags: Remove the USE Dynamic RTL check box. Otherwise, the DLL that is created requires Runtime Packages or Runtime Library. Save information in Win.ini with C Bulider
Many software now saves the data needed in the program in the registry, so when the software has more and more software, the registry is increasing, and the system is easier to make the system error. Of course, Microsoft also recommends saving data in the registry, but when we need to save data, you can save data in Win.ini for a while, which can be easily maintained, and the implementation is relatively simple. Here are how to do with Borland C Builder as an example. The principle is actually very simple, just call the API's WriteProfileString and getProfileint functions. The prototypes of these two functions is: BOOL WriteProfileString (LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString); UINT GetProfileInt (LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault); wherein means lpAppName WIN.INI middle name, i.e. with [] The string, lpkeyname refers to the name of each item in this section, and lpstring means the value of this project, the number after "=", NDEFAULT is the value returned when LPROFILEIN is not found, that is, the default value The former returns to the Boolean value (TRUE or FALSE), the latter returns to the unsigned shaping value. When LPKEYNAME is empty (NULL) in the WriteProfileString function, the content of this section is cleared, the content of this project will be cleared. The following example will illustrate the usage of these two functions. Create a new application, put two Edit and three button on Form1, where edit's text is empty, and the three Button's CAPTION is "Add", "View", "Clear". Double-click the "Add" button to join the following code: WriteProfileString ("Example", "Project", Edit1 → Text.c_STR ()); Double-click the "View" button to join the following code: unsigned int Temp; temp = getprofileint ("example program" , "Project", 100); Edit2 → Text = INTOSTR (TEMP); Double-click the "Clear" button to join the following code: WriteProfileString ("Examples", NULL, NULL; then press the F9 key to run the program. You can check the correctness of the program. Enter a number in Edit1, such as "3265", press the "Add" button, then run "Sysedit" to view the last side of the "win.ini" file, you can see the following: [Examples] item = 3265 Where "[]" and "=" are the function of the function. Press the "View" button, "3265" appears in Edit 2, when pressing the Clear button to clear the added part. Viewing the desired purpose has been achieved. Friends who love programming can apply the above methods into their own programs to achieve the role of saving data information. When you really want to save information to the registry, you can define an object of a Tregistry class in C Builder to perform related operations, or call the Windows API function, how to program you can see the relevant information or contact us. How to detect hardware in C Builder
In the process we have written, it is often dealing with hardware, so how is the device in the system in the program, what is its running status? For beginners, this problem is often unresolved, in fact, just use several API functions, hardware problems are not mysterious. Let's take a look at how to detect hardware in C Builder. 1. Test the CPU's model first let us start from the simplest, take a look at your own CPU model. First, in C Builder, the form shown in Figure 1 is drawn. In the following examples, we will always use this form for demonstration, which includes a METON for activating the test, and a MEMO used to display the results. . We can use the getSystemInfo this API to get the model number of the CPU. Add the following code to the Click event of the Button's on it: void __fastcall TForm1 :: Button1Click (TObject * Sender) {// get the CPU model SYSTEM_INFO systeminfo; GetSystemInfo (& systeminfo); Memo1 → Lines → Add (clicks Juan PU type Yes: 敚玈 Tring (systeminfo.dwprocessortype));} Run it, click TEST to try, the CPU model is coming out! 2. The method of detecting the memory state to obtain a memory state and the CPU model is almost, but he uses another API: GlobalMemoryStatus. Among them, members dwtotalphys are used to get the total amount of physical memory, and DWAVAILPHYS is the meaning of effective physical memory. As long as we add the following lines of code to the above programs (do not need to be done, the same): // Get memory status MemoryStatus memory; memory.dwlength = sizeof (Memory); // Initialize GlobalMemoryStatus (& Memory); MEMO1 → LINES → Add (撃 锢 砟? MB): 敚玈 TRING (Int (Memory.dwtotalphys / 1024/1024)))); MEMO1 → LINES → Add (fishing Zinca 捎捎 诖媸? KB) : 敚玈 TRING (int (Memory. / 1024)))))))) The format of the two programs is almost exactly the same. In fact, GetSystemInfoglobalMemoryStatus can also get many other information about CPU and memory, follow the above format to set up, more detailed information can look at C Builder4 Help. 3. Detecting the available hard disk space, after the warming up of the two simple questions, let's deal with a slightly complicated issue: We know that the installer has a process of detecting the hard disk space, then how is this implementation? He used The API function getDiskFreespace, the function enters a parameter: the path to the target disk; returns four parameters, the number of sectors per cluster, the number of bytes per sector, the number of idle clusters, total cluster number.
If we need to detect the total capacity and availability of the C disk, then add the following code to the above program: // Get the C drive DWord Sector, Byte, Cluster, Free; Long Int FreeSpace, Totalspace; GetDiskFreespace (揅:? & Sector, & Byte, & Free, & Cluster; // Get Return Parameters Totalspace = Int (Cluster) * Int (Byte) * INT (SECTOR) / 1024/1024; // Calculation total capacity free = INT (free) * int (byte) * int (sector) / 1024/1024; // Calculate the available space Memo1 → Lines → Add (MB): 敚玈 TRING (TOTALSPACE)); MEMO1 → Lines → Add (揅 Disk available space (MB): 敚玈 TRING (FREESPACE)); how? You can do your own installation now! How to respond to messages and custom messages in C Builder
Inprise (Borland) C Builder, you can respond as messages as in Delphi, just look slightly more complicated. For system-defined messages, you can respond directly: #define WM_MY_OPEN_CMDLINE_FILE (WM_USER 1) Custom Message Custom Message #define WM_MY_Search_Node (WM_USER 2) // Custom Message of Command Class Tsomeform: Public TForm { // ... other code protected classes: // void __fastcall OpenCmdLineFile response message (TMessage message); void __fastcall SearchDocumentNode (TMessage message); void __fastcall GetWindowMinMaxInfo (TWMGetMinMaxInfo message); // message achieved through the following macros the correct response BEGIN_MESSAGE_MAP MESSAGE_HANDLER (WM_MY_OPEN_CMDLINE_FILE, TMessage, OpenCmdLineFile) MESSAGE_HANDLER (WM_MY_SEARCH_NODE, TMessage, SearchDocumentNode) MESSAGE_HANDLER (WM_GETMINMAXINFO, TWMGetMinMaxInfo, GetWindowMinMaxIn fo) END_MESSAGE_MAP (TForm)}; // end class // the following is the code that implements void __fastcall TSomeForm :: OpenCMDLINEFILE (TMESSAGE Message) {// Directly passed the parameter lpstr lpcmdline = (lpstr) message.lparam; // from Message THIS-> HandlecMDLineFile (LPCMDLINE); // Process the parameters of the command line Return;} void __fastcall TsomeForm :: SearchDocumentNode (TMESSAGE Message) {// Response Message // Message Parameters Unquestied here. this-> SearchNode (); return;} void __fastcall TSomeForm :: GetWindowMinMaxInfo (TWMGetMinMaxInfo Messag e) {// set the minimum size of the main window MINMAXINFO * MinMaxInfo = Message.MinMaxInfo; MinMaxInfo-> ptMinTrackSize.x = 400; MinMaxInfo-> Ptmintracksize.y = 300; Return;} where: TMESSAGE and TWMGETMAXINFO type are defined: c: / program files / borland / cbuilder / inluCDE / VCL / Messages.hpp; other message response methods are the same. Alternatively, a corresponding message structure (such as tsearchnode_mes soable) can be defined for custom messages, as for how to define message structures, can be referred to: c: / program files / borland / cbuilder / inluCDE / VCL / Messages.hpp Using C Builder develops an animation DLL
When we perform a copy file, lookup file, or computer is more time-consuming operation, Windows displays a small movie, indicating that the operation is in progress, has a lot of color than the still image of the dead plate. Then we can also show such an animation prompt when we develop software yourself. When I developed a foreign trade application software system, I encountered the amount of data very large. When I was found through a composite condition, because each project of the database table has an index, it is expensive, the system will also show a long pause. Users feel extremely unhappy. After a period of exploration, I developed an animation DLL that can be used under the development environment PowerBuilder used. Due to the multi-threaded programming, the DLL function of PB calls can be resigned in time to PB, and does not affect the operation of the application system. Users can see something in motion, and will not think that the system stopped responding, the feeling time does not seem to have been so long. Code and Compilation Options (1) Select New under the File menu of C Builder, select DLL in the New Item dialog box, C Builder creates a blank DLL project. (2) Select New Form, C Builder under the File menu, create a blank Form, modify its properties to bordersty = bsdialog bordericons Substyle = fsstayontop position = poscreencenter name = statusform (3) in Form Add a Win32 Animate Control Animate1, modify its properties to align = altop (4) Add a Standard to the Button control button under the Form, add the Timer Control Timer1 under System, and set the Timer Interval Time Bit 250. Faster response to the user's cancellation request. Because the PB application system and the animation form code belong to two threads, you cannot use the PB thread to directly close the window of the movie windows. Timed check mark, once the shutdown flag is detected, turn off the window, clear the thread flag, and end the animation thread. The coding and encoding principle are given below: 1. DLL DLL body code:
/ ********************************** * DLL body code * Define DLL public variable * g_commonavi to Animate control animation Type index * gi_canceled button_cancel button is selected to pass the movie type to display, by the DLL output function as a parameter input * GI_REQUESTCLOSE Request movie thread closing flag * Gi_WindowAntive animation window Where is the status * Lpswinttentle animation form headline, by DLL output functions as an input parameter * / TCommonAVI g_CommonAVI [] = {aviNone, aviFindFolder, aviFindFile, aviFindComputer, aviCopyFiles, aviCopyFile, aviRecycleFile, aviEmptyRecycle, aviDeleteFile}; int gi_Canceled = 0, gi_AVIType = 0; int gi_RequestClose = 0, gi_WindowActive = 0; char lpsWinTitle [256]; HWND hWndParent = NULL; / * custom DLL output functions * / extern "C" __declspec (dllexport) int pascal DllEntryPoint (HINSTANCE hinst, unsigned long reason, void *); extern "C" __declspec ( dllexport) int pascal ShowStatusWindow (int AVIType, LPSTR WinTitle, long hWnd); extern "C" __declspec (dllexport) int pascal GetStatus (int ai_CloseWin); extern "C" __declspec (dllexport) int pascal CloseStatusWindow (); / * define threads TFORMTHREAD: * / Class TFormThread: Public Tthread {public: // user declarations __fastcall tformthre ad (bool CreateSuspended); void __fastcall Execute (void);}; __fastcall TFormThread :: TFormThread (bool CreateSuspended): TThread (CreateSuspended) {} / * animation thread executing code animation frame control timer closes it, clears after the end of the thread presence flag operation form * / void __fastcall TFormThread :: Execute (void) {gi_WindowActive = 1; StatusForm = new TStatusForm (NULL); StatusForm-> Caption = lpsWinTitle; StatusForm-> ShowModal (); gi_WindowActive = 0 DELETE STATUSFORM; GI_REQUESTCLOSE = 0;} / * Defines a thread instance pointer * / tFormThread * formthread; / ******************************************** **************** * Output Function Code Implementation section * DLLLENTRYPOINT 32-bit DLL Entry * ShowStatusWindow Displays the animation window, it creates a window by creating a thread,
Avoiding the control of the window's modal attributes to returning to the caller * getStatus to get the calorie state, that is, the user has no choice 撊 麛 button * CloseStatusWindow Close the animation window, * / __declspec (dllexport) int WinAPI DLLENTRYPOINT (DLLEXPORT) INT WINAPI DLLENTRYPOINT HINSTANCE hinst, unsigned long reason, void *) {return 1;} __declspec (dllexport) int pascal ShowStatusWindow (int AVIType, LPSTR WinTitle, long hWnd) {hWndParent = (HWND) hWnd; memset (lpsWinTitle, 0, sizeof (lpsWinTitle) ); strncpy (lpsWinTitle, WinTitle, sizeof (lpsWinTitle) -1); if (AVIType> 0 && AVIType <= 8) gi_AVIType = AVIType; FormThread = new TFormThread (true); FormThread-> Priority = tpNormal; FormThread-> Resume ();} __declspec (dllexport) int pascal GetStatus (int ai_CloseWin) {if (gi_Canceled) if (gi_WindowActive) {gi_RequestClose = 1; while (gi_RequestClose);} return gi_Canceled;} __declspec (dllexport) int pascal CloseStatusWindow () {if (gi_windowactive) {GI_REQUESTCLOSE = 1; While (gi_requestclose);} return gi_canceled;} 2. Form STATUSFORM code: TSTATUSFORM * STATUSFORM; // ------------------ ----------------- EXTERN INT GI_CANCELED; EXTERN INT GI_AVITY; EX Tern Tcommonavi g_commonavi []; __fastcall tstatusform :: tstatusform (hwnd parentwindow): tform (parentWindow) {gi_canceled = 0;} // ------------------------------------------------------------------------------------------------------------------------------ ------------ // Cancel button does not directly close the form, and indicate the set cancel sign for the call to view void __fastcall tstatusform :: button_cancelclick (Tobject * sender) {GI_CANCALED = 1; // MODALRESULT = mrcancel;} // ---------------------------------- // Activate the animation, in Formcreate event void __fastcall tstatusform :: formc (TOBJECT * Sender) {animate1-> commonavi = g_commonavi [gi_avitype]; animate1-> active = true;} // ------------- -------------------- EXTERN INT GI_REQUESTCLOSE
// Timer event detects the end flag closing form void __fastcall tstatusform :: Timer1Timer (TOBJECT * Sender) {ified {i (gi_requestclose) {modalResult = mrok;}} // ------------- -------------------- (5) Settings Compilation options: project-> Options Open the Project Options dialog box, clear the Use Dynamic RTL logo in the Linker property page, Clear the Build With Runtime Packages in the packages property page. This can be run as long as a single DLL is run without having to install some dynamic connection running time libraries. Compiling the DLL on the top of the movie DLL can be called by any other development language, and the method of use in the PB is given below. (1) defined: // Declare -> Global External Functions FUNCTION Long ShowStatusWindow (Long AVIType, String WinTitle, long hWnd) & LIBRARY "STATWIN.DLL" ALIAS FOR "ShowStatusWindow" FUNCTION Long GetCancelStatus (Long CloseWindow) & LIBRARY "STATWIN. DLL "ALIAS FOR" GetStatus "FUNCTION Long CloseStatusWindow () & LIBRARY" STATWIN.DLL "ALIAS FOR" CloseStatusWindow "(2) call: long ll_EndTime // Find the folder display animation ShowStatusWindow (2) setpointer ll_EndTime = Cpu (HourGlass!) () 10 * 1000 do if getcancelstatus (0) = 1 THEN EXIT End IF // Doing things to do Loop Until CPU ()> LL_ENDTIME CloseStatusWindow () Make screen saver with C Builder 3
The screen saver is a standard Windows executable that is SCR's extension. When the "Screen Sword" page of the Display Properties of the Control Panel, the module will automatically find extensions under the Windows Start Directory (Windows Directory and System Directory). The name is SCR's Windows-based executable. Using the screen saver, not only can extend the life of the display, but also protect private information. The preparation screen saver not only involves the processing of messages, but also involves processing of command line parameters. The strict standards must be complied with the Win32-based screen saver in the Win32SDK documentation. Follow these standards, the screen saver must output two functions: ScreenSaverProc and ScreensaverConfigureDialog, how many of the screen savers in the Windows system do not follow these standards (view you can use using the ImpDef or TDUMP utility). And use the method described in this document to write a screen saver, not only to use the resource editor, but also use the SCRSAVER.LIB file (in the C Builder3 environment when link). Not only should be related to the processing of messages, but also related to the processing of command line parameters. C Builder3 is a quick application development tool that provides many types of application development templates, but does not provide development screen saver templates, and does not mention how to develop such applications in its online help. . After this study, the method of compiling screen savers with C Builder3 is found. When setting up the "Screen Sword" page of the "Display Properties" item of the control panel, you should have three types of command line parameters, and the results of the screen saver in various situations are different. In general, three types of forms (or two are discussed in subsequent content). The following will specifically explain how to prepare a screen saver. First, the selection of the screen saver If a protector is selected in the drop-down list box titled "Screen Sword", the system will automatically start the program, and the display range of this program is displayed on this page. Screen range, at the same time, two command line parameters: one is "/ p"; the other is the handle of the display window, passing to this selected program. Therefore, such programs first should be able to handle command line parameters. In C Builder3, the function related to the command line parameter is: paramcount () and paramstr (), the specific declaration method is as follows: 1. EXTERNPACKAGEINT__FASTCALLPAAMCount (Void); This function returns the number of command line parameters, but does not include the application itself. 2. EXTERNPACKAGEANSISTRING__FASTCALLPARAMSTR (INTIndex); This function returns the command line parameters specifying the index value. Paramstr (0) returns the application itself. So, in this step, the statement determined in the steps is as follows: IF (Uppercase (paramstr (1)) == "-p" || Uppercase (paramstr (i)) == "/ p") {// addthecodeinhere} After completing the parameter judgment, the processing of the display window should be displayed to enable the program to display the program's parent window and display area.
This should involve the acquisition of the parent window handle and the setting of the parent window, and the call of the API function. The parent window handle in this environment is the second command line parameter passed; set the parent window, just set the form's ParentWindow property. This procedure is as follows: ReCtrc; // line1 hwndhwnd = (hwnd) (atol (paramstr (2) .c_str ())))))); // line2 :: getClientRectRect (hwnd, & rc); // line3 parentWindow = hwnd; // Line4 left = rc.left; // line5 top = rc.top; // line6 width = rc.right-rc.left; // line7 height = rc.bottom-rc.top; // line8 on the program fragment In the second line of statement, the second parameter is converted into a window handle; then, the third line of statement uses this window handle to invoke the API function to obtain the customer area of the window; the fourth line of line of statement will select the screen The parent window of the protection program is set to the specified window; the remaining statement is the client area size of the program's window size to the secondary window. The location of this program clip should be in the onCreate event processing of the form. It should be noted that the form pattern of this type (including a form introduced in the third step) should be: formstyle = fsstayontop; the style of the form boundary should be: borderstyle = bsnone; of course, there is no need for mouse graphics Therefore, the shape of the mouse can be set to CRNONE: CURSOR = crnone; Second, the setting of the initialization parameter is set to "Set" button in the "Settings" button in the Display Properties module, the system starts the specified protection. The initial value setting dialog of the program is: "/ c" or "-c" is: "/ c" or "-c" (the same as the above). Through this dialog, some initial parameters of the protection program can be set, such as the change in graphics. In this program, it is also related to the read and write of the initialization file or the registry to record the initialization parameters, which is easy to use when the protector is started. Third, the preview and operation preview is the display after the screen saver is activated. Click the "Preview" button in the "Screen Sword" page clicking the "Display Properties" page to observe the actual effect of the protector. At this time, the command line parameters passed when the system starts the program is: "/ s" or "-s". The processing of command line parameters is the same as the previous steps, but in this step, several messages are also processed, these messages are: WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN, WM_KEYDOWN, WM_AACTIVATE.
Forms and process WM_ACTIVATE WM_MOUSEMOVE message is as follows: void__fastcallHandleSomeMessage (TMessage & Msg) {switch (Msg.Msg) {// ...... caseWM_ACTIVATE: if (Msg.WParamLo == WA_INACTIVE) Close (); break; caseWM_MOUSEMOVE: if . (OldMouseX == - 1 && OldMouseY == - 1) // Intheconstructor, OldMouseXand OldMouseYmustbeinitializedby-1 {OldMouseX = Msg.LParamLo; OldMouseY = Msg.LParamHi;} elseif (OldMouseX = Msg.LParamLo || OldMouse = Msg.LParamHi!! CLOSE (); break; ...}} For other messages is just calling a close () function to close the application. When using such a message processing, the message mapping must be performed when defined, otherwise, it is necessary to perform processing in the corresponding message response (using a certain Boolean variable, you can use a form with the first step). Similar to the first step, in this step, the shape of the specific mouse pointer is also required, so set the mouse pointer to crnone: cursor = crnone; four, modify the project source file in C Builder3, one form That is, a class, in other words, classes with certain features are also a form, therefore, when preparing a screen saver, do not need the main form, and not to automatically create some forms, this When you want to modify the project source file, the program listed below is the project source file used when preparing a screen saver, for the reader's reference.
WINAPIWinMain (HINSTANCE, HINSTANCE, LPSTR, int) {CreateMutex (NULL, true, "ScreenSaver"); if (! GetLastError () = ERROR_ALREADY_EXISTS) {try {Application-> Initialize (); Application-> Title = "screen saver Test "; if (Uppercase (paramstr (1)) ==" / c "|| Uppercase (paramstr (1)) ==" - c "|| paramcount () == 0) {TscrsaverConfigueerf * SCRCFG = NewtscrsaverConfiguerf (NULL Scrcfg-> showModal (); deleteScrcfg; return0;} // click "Set" button elseif (Uppercase (paramstr (1)) == "/ p" || Uppercase (paramstr (1)) == "- P ") {Tscrforp * SCRFP = newtscrforp (null); SCRFP-> ShowModal (); deleteSCRFP; RETURN0;} // Select a program elseif in the Screen Sword drop-down list box (Uppercase (paramstr (1)) = = "/ S" || UPPERCASE (paramstr (1)) == "- s") {tscreensavef * screensave = newtscreensavef (null); screensave-> showModal (); deleteScreensave; return0;} // Click "Preview" Buttons, and run screen saver else return1;} catch (exception & exception) {Application-> showexception (& exception);}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} // ThewinMainFunctionEnd previously introduced the method of preparing a screen saver under C Builder3. For c Builder3 This RAD tool is to develop such a program is also quite convenient. According to the foregoing method, the screen saver can be developed in a very short time. For screen saver, it is not explained herein how to set the password problem, this part will be explored by the reader. TCP / IP head format
First, first is the common IP head format. IP head format: version number (4 digits) IP header length (4 digits) Service Type (8-bit) Packet Length (16-bit) Identification Section (16-bit) Sign Segment (16-bit) Survival Time (8) Transfer Protocol (8-bit) header checksum (16-bit) Send address (16-bit) destination address (16-bit) option padding
Brief Description ============ 1. IP header length calculation The unit is 32-bit words, which is common to calculate the data start offset 2. The length of the packet length is represented by byte, including the length of the head, Therefore, the maximum length is 65535 bytes 3. The time indicates that the data is saved on the network before being lost, in seconds. 4. The algorithm of the header checksum is the 16-bit and complement of all 16-bit words. 5 The length of the option is variable, the fill area changes with the option length to ensure the length of the entirety.
Description ============ Struct iphdr {byte Versionihl; Byte Tos; Word Tot_Len; Word ID; Word Frag_off; Byte Ttl; Byte Protocol; Word Check; DWORD SADDR; DWORD DADDR; / * PUTOS Here. * /}; 2, TCP head format TCP head format: Source port (16-bit) Destination port (16-bit) Sequence number (32-bit) confirmation number (32-bit) data offset (4 digits) Reserved (6 digits) Sign (6-bit) window (16-bit) checksum (16 digits) emergency pointer (16-bit) option pad
Brief description ============ 1. Data offset is used to identify the start of the data segment 2. The retention section 6 bits must be 0 3. The flag includes an emergency sign, confirm the flag, and the stack flag, heavy Set the sign, synchronization mark, etc. 4. The verification and calculation method is to add 16-bit binary inverse inverse and in 16-bit binary and in the middle. 5. The length of the option is variable, the fill area changes the length of the option to ensure the length of the entirety. 6. For more detail, please refer to the relevant information.
Description ============ Struct TCPHDR {Word Sourport; Word DestPort; DWord SEQN; DWORD ACKNO; BYTE HLEN; BYTE FLAG; Word Word Window; Word Chksum; Word Urgptr; / * Put Options Here. * /}
UDP
First, use UDP to use the API instead of the control.
The first program (ReadBufferUdp) is used to receive the cache.
"Destino" variable is very important, if you receive data from other places to buffer, you must set Destino = 0 and assign your value when you execute you you will send the package (after the execution it will have the address which Send) You the packet.). If you just want to receive data from a specified address, you have to set the variable destino =
."gventerrar" is used to abort the process. (Gvencerrar is set to global variables.)
Time setting. "INICIO 12" = 12 second.
The third program is used to prepare the Winsock program.
Second, the code
int ReadBufferUdp (unsigned long * Destino, void * T, int Size) {char Buffer [128]; SOCKADDR_IN SockAddr; int LenSockAddr = sizeof (SOCKADDR_IN); fd_set FdRead; struct timeval t_val; int Ret; time_t Inicio = time (NULL) ;
Application-> ProcessMess (); if (gventerrar) Return False;
FD_ZERO (& FDREAD); fd_set (gvsocket, & fdread); t_val.tv_sec = 0; t_val.tv_usec = 0;
While ((Ret = SELECT (0, & fdread, NULL, NULL, & T_VAL))! = 1 && (INICIO 12)> Time (NULL) &&! gventerrar) {fd_zero (& fdread); fd_set (gvsocket, & fdread); t_val .tv_sec = 0; t_val.tv_usec = 0; Application-> ProcessMessages ();} if (Ret! = 1) Return False; if (RECVFROM (GvSocket, Buffer, Size, 0, (LPSOCKADDR) & SockAddr, & LensockAddr)! = Size)
Return False;
IF (* destino == 0) {* destino = SockAddr.sin_addr.s_addr;} else if (* Destino! = SockAddr.sin_addr.s_addr) Return False;
Memcpy (t, buffer, size); return true;}
INT WriteBufferudp (unsigned long destino, void * t, int size) {sockaddr_in sockaddr; int sche
Application-> ProcessMessages (); SockAddr.sin_family = AF_INET; SockAddr.sin_port = gvPortUdp; SockAddr.sin_addr.s_addr = Destino; Sent = sendto (gvSocket, (char *) T, Size, 0, (LPSOCKADDR) & SockAddr, sizeof ( SockAddr); if (Sent! = Size) Return False; Else Return True;}
Void INICIALIZATCPIP () {
Word wversionRequested; in_addr in; pservent pservent; sockaddr_in sockaddrin; wversionRequested = Makeword (1, 1);
IF (WSAStartup (WVersionRequested, & WSADATA) {ShowMessage ("Erro Na INITILIZAO DO TCP / IP"); Application-> Terminate (); Return;}
// Get The Port On Service File IF ("Your_Service_Name", "UDP")) == NULL) {ShrowMessage ("Erro Obtendo Port Do servi Transu / UDP"); Application-> Terminate (); Return;} gvportudp = pservent-> s_port; sprintf (Straux, "Servi Transurb / UDP Port:% D", NTOHS (GVPORTUDP)); log (straux);
// Open de Socket IF ((GVSocket = Socket (AF_INET, SOCK_DGRAM, 0) == Invalid_socket) {ShroSsage ("Erro Na Crtiao Do Socket"); Application-> Terminate (); Return;} log ("Socket CRIADO "); // do the bind sockaddrin.sin_family = AF_INET; SOCKADDRIN.SIN_PORT = GVPORTUDP; SOCKADDRIN.SIN_ADDR.S_ADDR = NULL;
IF (Bind (gvsocket, (lpsockaddr) & sockaddrin, sizeof (sockaddrin) == Socket_ERROR)
{ShrowMessage ("Erro No Bind Do Socket"); Application-> Terminate (); RETURN;} log ("Bind Do Socket COM Sucesso);
}
Judging the Desktop and other directories of Windows
Use the API function ShgetSpecialFolder. SHLOBJ.H has the prototype statement of Shgetspecialfolder. This function can help us find the Windows Desktop directory, start the directory, my document directory, etc.
SHGETSPECIALFOLDER requires three parameters. The first parameter is hWnd, which specifies the "Owner Window": The dialog or message box that may appear when calling this function. The second parameter is an integer ID that determines which directory is to look for the directory, and its value may be:
My computer CSIDL_FONTS font directory CSIDL_NETHOOD CSIDL_NETWORK Network Neighborhood My Network Places virtual folder CSIDL_PERSONAL My Documents CSIDL_PRINTERS printer CSIDL_PROGRAMS program group CSIDL_BITBUCKET Recycle Bin CSIDL_CONTROLS directory CSIDL_DRIVES control panel CSIDL_DESKTOP Windows Desktop desktop CSIDL_DESKTOPDIRECTORY desktop of CSIDL_RECENT most recently opened documents listed a CSIDL_SENDTO "Send Go to "Menu Item CSIDL_STARTMENU Task Start Launch Menu Item CSIDL_STARTUP Start Directory CSIDL_TEMPLATES Temporary Document The last parameter is the PIDL address. ShgetspecialFolderLocation Write the address to the PIDL.
The following code demonstrates how to use ShgetSpecialFolderLocation:
/ / -------------------------------------------------------------------------------------------- ---------------------- Void __fastcall tform1 :: button1click (TOBJECT * Sender) {LPITEMIDLIST PIDL; LPMALLOC PSHELLMALLOC; char SZDIR [MAX_PATH];
if (SUCCEEDED (SHGetMalloc (& pShellMalloc))) {if (SUCCEEDED (SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, & pidl))) {// if successful, returns true if (SHGetPathFromIDList (pidl, szDir)) {Label1-> Caption = szDir;}
Pshellmalloc-> free (pidl);} pshellmalloc-> release ();}} // -------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------- Note: Some directories are empty. Some specific directories do not have a corresponding directory on this file system.
Get the name and IP address of the local Internet machine
First, the following example uses the Winsock API to obtain the name and address of the local host and address void __fastcall tform1 :: button1click (Tobject * sender) {hostent * p; char s [128]; char * p2;
// Get The Computer Name GethostName (S, 128); P = gethostByName (s); Memo1-> Lines-> add (p-> h_name);
// get the ipaddress p2 = inet_ntoa (* (in_addr *) P-> h_addr)); Memo1-> Lines-> Add (p2);
Void __fastcall tform1 :: formcreate (TOBJECT * Sender) {Word WVersionRequested; Wsadata Wsadata
// Start Up Winsock WVersionRequested = MakeWord (1, 1); WSAStartup (WVersionRequested, & WSADATA);
Void __fastcall tform1 :: formdestroy (TOBJECT * sender) {wsacleanup ();}
Create a digital signature with C Builder
If you pass a data on the network, there is a unsafe factor, so that you can reach the destination for the data, and you can add a digital signature to the data. This allows the other party to check if the data you have passed is modified by others by verifying the signature.
First, the principle of program
The working principle of digital signatures is still relatively simple. It is based on the original data you provide, which produces a specific data signature, and the other party also generates a signature through the same process. If the data has been modified, then it is impossible. Get two models of exactly the same signature, so that data has been modified by others. Programmaker uses Windows's CAPI interface to achieve encryption, decryption, and digital signatures of data.
Second, the program list
Let's take a look at its specific implementation process by following the statement of C Builder. First create a digital signature, assume that its data comes from a file. // Variable declaration: HcryptProv HProv; // CSP Handle Hcrypthash Hhash; // Handle const amount = 4096; // Buffer size constant Byte PBuffer [buffer]; // Store read file content buffer BYTE Psignature [256]; // Store Signed Buffer Dword Dsignaturelen = 256; // Signed Length TFileStream * SourceFile; // A File Flow IF (! CryptacquiRecontext (& HPROV, NULL, NULL, PROV-RSA-FULL, 0) ) / / Connect the default CSP, accept its handle to put the HPROV {// error handling} if (! CryptCreateHash (HPROV, CALG-MD5, 0, & Hhash)) // Create a hash object, get it Handle is placed in hhash {// error handling} do {dreadlen = sourcefile-> read (pBuffer, buffer); if (! CryptHashData (Hhash, PBuffer, DREADLEN, 0)) // calculates the file according to the contents of the file {/ / Error handling}} WHILE (! (! "); If (! Cryptsignhash (hhash, at-signal, null, 0, psignature, & dsignatelen) // use private key to digitally sign the hash value // The signature data is placed in Psignature, and the length is placed in DSIGNATURELEN // error handling} to check the file-based data signature.
// Variable declaration: HcryptProv HPROV; // CSP Handle Hcrypthash Hhash; // Handle HcryptKey HpublicKey; // Public Key Handle const Int buffer = 4096; // Buffer size constant BYTE PBUFFER [buffer]; / / Save the bufferstream * sourcefile of read file content; // A file stream Byte Psignature [256]; // The last signature buffer dword dsignaturelen; / / The length of the signature of the last signature IF (! CryptacquiRecontext) (& HPROV, NULL, NULL, PROV-RSA-FULL, 0)) / / Connect the default CSP, accept its handle to put the HPROV {// Error handle} if (! CryptgetuserKey (HPROV, AT_SIGNATURE, & HPUBLICKEY); // Get a handle of the public key {// error handling} if (! CryptCreateHash (HPROV, CALG-MD5, 0, & Hhash)) // Create a hash object, get its handle to put it in hhash {// error handling } Do {DREADLEN = SourceFile-> Read (PBuffer, Buffer); if (! CrypthashData (Hhash, PBuffer, Dreadlen, 0)) // calculates the quota value {// error processing according to the contents of the file}} while (! Dreadlen Method for switching with ENTER key control focus In the Windows environment, you can get a control to get a focus, you can use the mouse to click on the control on the control, or press the TAB button to move the focus to the control. This control focus switch is not convincing. As shown in the figure, users will hope with Enter keys, and the control focus is switched from Edit1 to Edit2. To realize this, the function can be completed by helping the WinAPI function SendMessage. The method is: first set up the keypreview attribute of Form1 as true, then add the following code in the Form1 onkeyPress event. In this way, the user can move by pressing the ENTER, the key control focus is moved by definite Taborder order! Void __fastcall tform1 :: formkeypress (Tobject * sender, char & key) {if (key == vk_return) {SendMessage (this-> handle, wm_nextdlgctl, 0, 0); key = 0;}} block Windows message - - Orland C Builder API back door ---- Pillage ---- C Builder is worthy of Borland's excellent products, using it to develop Windows programs very fast, but you will also find some restrictions in programming, so you can't achieve your own ideas. For example, you can't modify the system menu of the form; for example, when using the tracking bar, you can't find the StartTrack and EndTrack events, and your procedure requires these two events. In Windows API programming, you will not have these troubles, just process the WM_SYSCOMMAND and WM_HSCROLL (or WM_VSCROLL) messages, the above functions can be implemented. The disadvantage of the Windows API is that it is very troublesome, too much time to consume on the details, but its function is the most powerful. The VCL of C Builder is functionally only a subset because the VCL is encapsulated on the API, and some unused functions are prepared. But the programmer's imagination is not encapsulated. They always have a big enthusiasm to achieve other ideas, modify the system menu and add StartTrack and NDTRACK events for the tracking bar. But the VCL does not have these functions, what should I do? ---- Fortunately, Borland did not block roads, but left a back door - allowing programmers to intercept and handle Windows messages, just like API programming. So, the method has ... ---- Method ---- Intercepting Windows Messages The following steps are required: ---- In the table single header file (such as Unit1.h) ---- 1. Create a message mapping table in the class declaration, handle the processing of a message Give the custom message handler. Begin_MESSAGE_MAP Message_Handler (Windows Message Name, TMessage, Message Processing Function Name) Message_Handler (...) end_MESSAGE_MAP (TFORM) ---- 2. Declaration Message Processing Functions in the Private Area of Class Declaration. Private: // user declarations void __fastcall message processing function name (TMESSAGE & Message); within the form file (such as Unit1.cpp) ---- 3. Write the message handling function, here you implement the features you need. For example, void __fastcall mainform :: onwmhscroll (tMersage & message) {... // Add your own code TFORM :: Dispatch (& Message); ---- Explanation ---- 1. About TMESSAGE ---- tMessage is a VCL predefined structure, defined as follows: struct tMessage {unsigned int msg; // message int wparam; // word parameter int Lparam; // long word parameter int result; // message result}; ---- 2. About TFORM :: Dispatch (& Message) ---- Custom message processing function is best added to TFORM :: Dispatch (& Message), this sentence is to let the message continue to pass. If this sentence is not, the message will be completely intercepted, and the VCL class may fail to achieve normal functions due to the message. ---- Example 1: Modify System Menu ---- There are some programs, the main window is small, the menu is not, if you want to join about or setup dialogs, the best way is to take the system menu. In Windows API programming, modify the system menu is the same as implementing other functions, not too easy, and it will not be too difficult. However, in C Builder, the table class (TFORM) does not provide any properties and methods of the system menu, implementing other features, and the modification system menu seems to be difficult to go on the sky. ---- Fortunately, Borland allows programmers to process Window messages, so the opportunity is coming! First, modify the system menu with the Window API function Assume that the form is MAINFORM, set the mainform :: oncreate () function: 1. Get the system menu handle with GetSystemMenu (Mainform-> Handle, False); 2. Modify the system menu with Appendmenu, DELETEMENU, and ModifyMenu function, assign the new ID number to a custom menu item. At this time, you can see that the system menu is also modified, but the custom menu item cannot be responded. Second, intercept the WM_SYSCOMMAND message in response to the custom menu item in the form of the table (such as Unit1.h) 1. Add a message response table at the end of the form class, get the processing of WM_SYSCOMMAND messages begin_MESSAGE_MAP Message_Handler (WM_SYSCOMMAND, TMESSAGE, ONWMSYSCOMMAND) end_MESSAGE_MAP (TFORM) 2. Add message processing function declaration in the Private area defined by the form class. Private: // user declarations void __fastcall onwmsysCommand (TMESSAGE & Message); In the form file (such as Unit1.h) 3. Write a message response function void __fastcall tform1 :: onwmsyscommand (tMESSAGE & Message) {f (message.wparam == id_sysmenu_myitem) {// Your Code Here, Do Something} TForm :: Dispatch (& Message); Third, the full program example Example 2: Add OnStartTrack and OneendTrack events to the tracking bar When the tracking column is used for progress control, OnStartTrack and OneendTrack are likely to be the event you need. For example, when controlling multimedia play progress, when the user moves the slider, you will need the onStartTrack event to stop playback, you need the OneendTrack event to locate the new play position. But Borland did not provide these two events, and I have such programming enthusiasts to self-reliance, and the idea of intercepting Windows messages. First, intercept the WM_HSCROLL message, add an onStartTrack and OneendTrack event to the trackball In the table single header file (such as Unit.h) 1. Add a message response table at the end of the form class definition to hand over the WM_HSCROLL message processing to the ONWMHScroll function. Begin_MESSAGE_MAP Message_Handler (WM_HSCROLL, TMESSAGE, ONWMHSCROLL) END_MESSAGE_MAP (TFORM) 2. Add the ONWMHScroll function declaration within the Private area defined by the form class. Private: // user declarations void __fastcall onWmhscroll (TMESSAGE & Message); 3. Join the StartTrack and EndTrack function declaration within the Private area defined by the form class. Private: // user declarations void __fastcall trackbar1startTrack (TOBJECT * Sender); Void __fastcall trackbar1ndtrack (TOBJECT * Sender); within the form file (such as Unit.cpp) 4. Write the OnWMHScroll function, so that it can call the StartTrack and EndTrack function according to the message parameter, generate an onStartTrack and OneendTrack event in the actual sense. 5. Write the StartTrack and EndTrack function. If it is a vertical tracking bar, change the above WM_HSCROLL to WM_VScroll. Second, the full program example end Borland C Builder programming, intercepting Windows messages is an advanced programming technology that allows you to try to explore Windows's potential, especially let programmers who have programmed with API have been comfortable. Intercepting the Windows message is the stage where the API is funny. When VCL can't do anything for you, please think of the bottom API. Use COMMATEXT Sometimes a convenient way to store a StringList, which is only a simple line. For example, when you want to use an INI file, how to write a line to an Ini file, you can complete this work with COMMATEXT. Here is an example, the function is to create a Blah.ini file and write a value in the following form: [My section] MEMO1 = (Your text you entered in MEMO1) 1. There are two buttons on Form1 btnload and btnsave and a MEMO1 2. Also join: #include 3. Define variables: const string inifile = "black.ini", inisection = "my section", inIvalue = "MEMO1"; 4. Save button code: void __fastcall TForm1 :: btnSaveClick (TObject * Sender) {TIniFile * ini = new IniFile (ExtractFilePath (Application-> ExeName) iniFile); ini-> WriteString (iniSection, iniValue, Memo1-> Lines- > COMMATEXT); delete ini;} 5. Load button code: void __fastcall TForm1 :: btnLoadClick (TObject * Sender) {TIniFile * ini = new TIniFile (ExtractFilePath (Application-> ExeName) iniFile); Memo1-> Lines-> CommaText = ini-> ReadString (iniSection , inivalue, ""); delete ini; 6. The following code after sorting the content loaded support, the actual storage unchanged: void __fastcall TForm1 :: btnSortLoadClick (TObject * Sender) {TStringList * sl = new TStringList; TIniFile * ini = new TIniFile (ExtractFilePath (Application-> ExeName ) inIfile); SL-> Commatext = INI-> ReadString (Inise, INIVALUE, ""); SL-> sort (); memo1-> lines = sl; delete INI; delete sl;} frame First, the software enters the main window, first display a message, tell the user some information about the software, such as software name, version number, etc. This information frame automatically disappears after 1 to 2 seconds. 1. Establish a New Application, then the system automatically generates a FORM1, which is the main form. 2.File-> New Form establishes a new form2, this as a message box. 3. Add a component TTIMER (on the System control bar on the Form2 to set the display time of the information box. 4. Ttimer's event ontimer Add: Form2-> Close (); 5. Add: Application-> Createform (__ classid (tform2), & form2); form2-> showmodal (); // This sentence must be added to Application-> Run (); and to put the head of Form2 File unit2.h includes the project1.cpp to WinMain (). 6. Operating the program, first display FORM2, the display time is determined by the TTIMER's interval attribute, 1000 is one second. Second, the implementation of the implementation of the software cover is the process of the current software design, and the program is made as a seal before the program is completed, and the screen is used as a sealing. It is often 1/4 screen size, showing the name of the software, the author, version of this information. It is very simple to use C Builder to realize this: 1 Customize a window TSPLASHFORM, set it into a "transmissive window", that is, all the options under Bordericons are set to false, borderstyle = bsnone, FormStyle = fsstayontop, position = poscreencenter; 2 Place a TPANEL in the TSPLASHFORM window (in the figure in the figure); 3 Place a TIMAGE control on the TPANEL to transfer the desired graphics; 4 Take a slightly modified WinMain function, add the code as shown below. What you need to point out is that this code is passed through the function FindWindow, and whether there is a window title "DEMO" should be stored in the memory. If you save, you will run out. This function can prevent the re-run operation. This setting is required in some fields. WinAPI Winmain (Hinstance, Hinstance, LPSTR, INT) {Try {IF (FindWindow (Null, "Demo")! = 0) {Application-> MessageBox ("Program has been run!", "Warning", MB_ICONSTOP); Return 0 } Tsplashform * splash = new tsplashform (application); Splash-> show (); Splash-> Update (); Application-> Initialize (); Application-> CREATEFORM (__ classid (tform1), & form1); Splash-> close (); Delete Splash; Application-> Run (); } Catch (Exception & Exception) { Application-> Showexception (& Exception); } Return 0; } How to get the command line parameter of the program? You can solve this problem with both different techniques below. Tips 1: First, perhaps the easiest way is to call the VCL Parastr () function. You can use the paramcount () function to determine how many command line parameters have passed to the application. Paramstr requires an integer parameter and returns an Ansistring object. If the parameter is 0, Paramstr will return the full name path of the executable. If the parameter is 1, the program name and the first command line parameter will be returned. If the parameter is 2, the second parameter will be returned, and so on. As a practice, open a new project, put 5 Label on the main window, add the following code to the window constructor: Label1-> CAPTION = paramstr (0); label2-> caption = paramstr (1); label3-> caption = paramstr (2); label4-> caption = paramstr (3); label5-> caption = paramstr (4); Run the program again. It is generally possible to see a similar string: E: /cbuilder/projects/project1.exe If you do not pass parameters to the program, then Label2 to Label5 is an empty string. Close the program, select Run | Parameters from the C Builder menu. Enter a few parameters (-debug -testing -param) run the program again. You will see: E: /cbuilder/projects/project1.exe -debug -testing -param Tip: Paramstr's intelligent judgment on the space in the directory. To confirm this, copy the generated EXE file to the Program Files directory and then run it, you will see Paramstr (0) to return the full path and contain spaces. Tips 2: The second method is to call the getcommandline API function. Getcommandline does not require parameters, and returns a C-style char *, which contains all of the command line parameters. You will have to solve the string to get the relevant parameters. Label5-> CAPTION = Ansistring ()); After running, Label5 will: "E: /cbuilder/projects/project1.exe" -debug -testing -param How to monitor clipboard In Form1.h PRIVATE: Void __fastcall clipboardchanged (tMESSAGE & MSG); Pack in Form1.h Pack: Begin_MESSAGE_MAP Message_Handler (WM_DRAWCLIPBOARD, TMESSAGE, CLIPBOARDCHANGED END_MESSAGE_MAP (TFORM) In .cpp Form1 plus: void __fastcall TForm1 :: ClipboardChanged (TMessage & Msg) {POINT MousePos; GetCursorPos (& MousePos); PopupMenu4-> PopupComponent = Form1; PopupMenu4-> Popup (MousePos.x, MousePos.y); / / A variation, pop up a menu, copy, cut, or clear this function} There Form1 in the .cpp a ToolButton void __fastcall TForm1 :: ToolButton9Click (TObject * Sender) {static HWND LastHandle; static bool clip = false; if (clip == true) {ToolButton9-> Down = false; ChangeClipboardChain (Form1- > Handle, Lasthandle); // End Monitor} else {Toolbutton9-> Down = true; clipboard () -> Clear (); Application-> minimize (); LastHandle = setClipboardViewer (Form1-> Handle); // Start monitoring } Clip =! Clip;} How to use onIdle events Use the OnIdle event to monitor the clipboard content at any time to change the executables of the pop-up menu. In Form1.h PRIVATE: Void __fastcall onder (Tobject * Sender, Bool & Done); Plus in form1 .CPP: void __fastcall tform1 :: onidle (TOBJECT * Sender, Bool & Done) {bool textSelected = DBRICHEDIT1-> SELLENGTH> 0; N17-> Enabled = TextSelected; // cut, copy, clear N18 -> Enabled = TextSelected; N20-> Enabled = TextSelected; bool CBHasText = Clipboard () -> HasFormat (CF_TEXT); // need to add #include Write a serial asynchronous communication program under WIN 95 with C Builder 4.0 · Basic method for serial port manipulation · Under Win32, the operation of the serial port is turned on or off like the file, and reading and writing to serial data can be performed in the user-defined read and write buffer. The specific function is: First use createFile () to open the communication serial port, where parameter lpFileName points to the serial port logic name, such as "COM1" or "COM2", etc., the parameter dwdesiredAccess defines the read and write permissions of the file, generally set to generic-read | generic-write; parameter dwsharemode definition Resource sharing method must be set to 0, for exclusive ways; LPSecurityAttributes define security properties, Win 95 is null; dwcreationDistribution definition file creation mode; dwflagsandattributes define file properties and tags, should be file-flag-overlapped, indicating asynchronous Communication method; HTemplateFile points to a handle of a template file and NULL under Windows 95. The serial communication parameters (such as baud rate, stop bit, data bit, check digits, etc.) are then set with the buildcommdcb () and setcommmmdcb () and setcommmmdcb () functions, such as baud rate, stop bit, data bit, check digits, etc. in which characters in buildcommdcb () are then The string parameter LPDEF defines the parameter format of MODE in the DOS command. About DCB more specific settings require specific definitions of data streams, handshake signals, and communication control requirements, see Windows Technical Information. Use getcommState () to get the current DCB parameter value. If you need to reset the timeout parameters of read-write by setcommtimeouts () and getcommtomeouts (); the settings of the read and write buffer use setupcomm (), parameters dwinqueue, and doutqueue are defined as the size of the input and output buffers, respectively. After the serial port is initialized, it is necessary to establish an event object related to communication. Generally use the createEvent () function, it returns an event handle, where the parameter lpeventattribute points points to the security attribute structure address, which is null in Win 95 (unsafe attribute); Boolean BmanualReset defines event reset, true represents manual reset, False Represents the auto reset (the correlation function is setEvent () and resetEvent ()); parameter binitialState defines the initial state of the event, TRUE represents the signal, otherwise it is not signal; LPNAME is the event name set for multi-process, for single-process definition as NULL. Then use setcommmask () to define the user program to monitor the communication event category. After the above setting is completed, the user program can wait for the generation of the communication event, generally call the function waitcommEvent () to monitor the communication event, where the parameter lpevtmask points to the mask address generated, and the nature of the event is determined, and LPoverlapped points to the overlapping structure address. Simply defined as NULL. For the response to serial port events, there are four ways: query, synchronous I / O, asynchronous I / O and event driver I / O, need to be determined according to different control requirements of users. The query mode takes up longer computer time, synchronized I / O mode to return until the specified byte number or timeout is read, it is easy to cause thread blocking, asynchronous I / O is used for background processing, the event driver is notified by the system The event of the program is incident and serial port operation. Comparison of events drive I / O methods are flexible. When there is a communication event, the function readfile () and writefile () can be used directly to read and write the serial buffer. Where lpbuffer points to the read and write buffer, nNumberofbytes is the number of bytes to read and write, lpnumberofbytes are actually read and written bytes, and LPoverLapped specifies synchronous or asynchronous operations. After the communication is over, the call function closeHandle () is turned off. · Application example With the above API function, the author gives an instance of the simplified serial port initialization. 1 is an interface example of a serial communication basic parameter setting generated using a C Builder component. Handle hcom; // Define the handle DCB DCB; Overlapped e; / / Define overlapping structure Void -fastcall TFORM1 :: Okbtnclick (TobjectSender) {hcom = CreateFile ("COM2", Generic-Read | generic-write, 0, null, open-existing, file-attribute-normal | file-flag-overlapped, null); // Open the communication port Buildcommdcb ("9600, O, 8, 1", & DCB); / / The first string parameter is actually used by Figure 1, after the combination of Figure 1, only simply describes its format Setcommstate (HCOM, & DCB); SetupComm (hcom, 512, 512); // Setting the read / write buffer E.hevent = CreateEvent (NULL, FALSE, FALSE, NULL); // Setting Event Setcommmask (hcom, ev-rxchar | ev-txempty); // Set an event mask Okbtn-> enabled = false; Message processing techniques for C Builder non-visual components A non-visual component must respond to a Windows operating system or user-defined message. However, since a non-visual component has no window, it does not have a window handle, naturally it does not receive the message, in order to solve this problem, our idea is to create a hidden window to make non-visual components to receive news. To create a hidden window for your non-visual components, you need to have the following: 1. A private variable type (private variable type) hWnd to obtain a window handle. 2. A function (A WndProc) used to capture the window sent to the component. 3. Create a window handle and set WNDPROC for the call to AllColatehWnd. In order to clearly explain the above ideas and display creation, the following we will explain with a specific example. First we first create a new component, in C Builder, select File | New ... Double-click Component icon to display a new component dialog to change Ancestor Type to tComponent and Class Name TTEST and is set. Then, switch to the header file of the new component, add the following declarations in the private part of the class: HWND FHANDLE; Void-fastcall WndProc (TMESSAGE & MSG); The first line declares an HWND variable that calls FHANDLE, which will be used to capture the window handle after the window is created. The second line declares a WndProc function for receiving messages. The statement of this function must be identified in order to define it is a WndProc, then construct the following statement in the class declaration public (public) section: VIOD DOIT (); This public function will be used to test components, and the class declaration should be as follows: Class Package TTEST: PUBLIC Tcomponent { Private: HWND FHANDLE; Void-fastcall WndProc (TMESSAGE & MSG); protected: PUBLIC: -fastcall ttest (TComponent * Owner); Void Doot (); -published: } Now switch to the component's code unit, add the following line to the top of the unit (maybe a good place on the function) #Define my-message.wm_user 1 This line declares that when the DOIT function is called, the component will send it to its own user-defined message. At this point we have to assign a window handle for the component. This handle will provide a hidden window that allows us to capture messages in the component. Find the component constructor, add the following code: -fastcall test :: test (Tcomponent * Owner) : Tcomponent (Owner) { Fhandle = allocatehwnd (WndProc); } Ok, the important step has been completed, the allocatehwnd function creates a hidden window and returns its handle, note that we will send Windows where to send a message, pass the address of WndProc; Now let's create a part of the WndProc. Add: Void-fastcall ttest :: WndProc (TMessage & msg) { IF (msg.msg == my_MESSAGE) MessageBox (0, "Got Here!", "Message", 0); Try { Dispatch (& msg); Catch (...) { Application-> HandleException (this); } } Whenever Windows sends a message to the component, Windows calls this function whenever Windows. This part of the code has completed two things. First, it checks if the received message is our user-defined message. If so, a message box will be displayed, you can see the message we have received. Secondly, this code transmits messages during the system (or VCL) process, and the TRY / CATCH block is used to ensure that if an abnormality occurs, it will become a handle under the default style. In summary, the WndProc function is sent to all other messages for the default handle to monitor all customer messages. Now we create a DOIT function, complete our components, join us to create a DOIT function, complete our components, join the code: Void TTEST :: DOIT () { Postmessage (Fhaandle, MY-Message, 0, 0); } This function sends a window handle of a message component (remember that this window handle is previously stored in the FHANDLE data finished product). Now we have completed the creation of component selection, with SELECTFILE | ColSeall to save our work test components. The next step will test the component. If you use BCB3, you must join the component into "PackGE), then use Componet | Install (you can use DCLSTD35 Packe to quickly test). Select the testbb.cpp you just exist. Once you have installed the completion of the component, it will appear on the component board. Double-click the button, create the following code for the button's onclick event: TEST1-> DOIT (); Now run the program. When you click the button, you will see a message box to display "Got Here". Listinga and B include header files and source code below. Summary: A non-visual component that can respond to Windows messages has many purposes. The most obvious is to encapsulate some aspects of WindowsAPI. For example: TAPI and WINSOCK send messages to the specified user of the event. If you write the components encapsulated a such API. You will need to capture messages sent by Windows. Join the hidden window in your component will help you do this. The above programs are debugged in C Builder 3.0. Establish Database VCL Use experience with C Builder With the wide application of the database, database programming has become a rapid development of programming. The powerful feature of C Builder in database development is unparalleled, and you can even generate a beautiful database program without writing a program. Let's take a look at the use skills of several database VCLs in C Builder: First, DBGRID control 1. Set the field display width attribute of DBGRID In order to create a smaller column in DBGRID, you must establish a display title, which is equal to or less than field values. For example, you want to build a column with only three characters wide, your column header shows that there must be only three characters or less. 2. Change the display field and date display format of DBGRID (1) Double-click the table1 corresponding to the DBGRID to enter the field editor. (2) Right-click "Add Fields ...", the Add Fields ... ", the Add Field dialog box, select the field you want to add (this field will be displayed by DBGRID when running) and point OK button. (3) Assumption Add the "Date" field, click this field, in the property table: DISPLAYLABEL Fill in the field name you want DBGRID display. If the original field name is in English, here DBGRID will display the Chinese name with the Chinese name. Fill in DISPLAYFORMAT: YYYY-MM-DD, will be displayed in 1999-05-28 format later. Second, TQUERY control The TQuery control is a very important control in database programming. It is responsible for establishing contacts with the database through BDE and the SQL statement is conveniently established. Query must establish the corresponding SQL to take effect. The parameter setting of TQuery is as follows: (1) In the SQL attribute: SELECT * FROM table name Where field name =: variable name Follow the ":" is the variable. After writing, the data type of the variable can be modified in the parameter properties. (2) Assignment of variables: Query1-> Active = false; Query1-> params-> items [0] -> asstring = edit1-> text; Query1-> Active = true; / / Find records that match the variable (3) Display the result with DBGRID DBGRID's DataSource is connected to DataSource1, while DataSource1's DataSet is connected to TQuery1. Third, the application example The query established by the QUERY control is easier and more efficient than Table. Use a simple code to explain how to establish a query program: For example, to create a program name book1 booking book 1 book 1, add DBGRID, DataSource, Query on the form, add the following code: DBGRID1-> DataSource = Datasource1; DataSource1-> DataSet = Tqery1; Query1-> close (); Query1-> SQL-> CLEAR (); Query1-> SQL-> Add ("SELECT * FROM table where (book name = 'BOOK1'"); Query1-> EXECSQL (); Query-> Active = true; You can see all names BOK1 records in the generated table. Create an Internet-based point-to-point chat with C Builder ---- Create an Internet-based application, you might think of complex Winsock programming. However, C Builder3 provides new WebBroker's Internet kits, where the TclientSocket and TServersocket components encapsulate the API of Windows, which greatly simplifies Winsock programming. To transfer data over Internet, at least a pair of Sockets, a socket on the client, another socket on the server. In fact, TClientSocket, TSERVERSOCKET components are not Socket objects, and its properties socket will return their respective socket objects. TclientSocket is used to handle the socket connection between the client to the server side. TSERVERSOCKET is used to process the socket connection from the client. Once the client and the server are connected to the socket, the client, and the server can communicate with each other. . ---- Establish a new project to create an application user interface: ---- 1. Switch the component page to the Internet page, put a TSERVERSOCKET component and a TclientSocket component to the form, so that the application can be both TCP / IP servers or TCP / IP customers. Set the port attribute to the same value (such as 1000), determine the connection type between the socket is Nonblocking. ---- 2. Put two TMEMO components to the form to display both parties' conversation, set the memo2's ReadOnly property to True. ---- 3. Put a panel component at the top of the form, putting three buttons on it: Listening (BTNConnect), disconnected (btndisconnect), is used to initiate the corresponding operation. ---- 4. Place a STATUSBAR component at the bottom of the form, set its SimplePanel property to true, change the status strip information in the corresponding event handler, so that the user knows the connection status at any time. ---- Open the header file, add two private members to the private member: BOOL ISSERVER; STRING Server. When both parties are in communication, ISSERVER is used to determine which CHAT program is in the server side, Server is used to store the host name of the server. The constructor that establishes the form class is as follows: __fastcall tform1 :: tFORM1 (TComponent * Owner: tform (ooner) {isserver = false; server = "localhost"; ---- SERVER is set to localhost by default, so that the program can debug on a single machine that is not connected to the Internet. In the Windows subdirectory you can find the hosts.sam file, you have defined the host name: localhost in this file: Localhost. Void __fastcall tform1 :: formcreate (TOBJECT * Sender) {btndisconnect-> enabled = false; ---- After the program runs, if the user presses the "listening" button, set the program to the server side, then the TSERVERSOCKET's Active property should be set to TRUE, so that the server automatically enters the listening state. void __fastcall TForm1 :: btnlistenClick (TObject * Sender) {ClientSocket1-> Active = false; ServerSocket1-> Active = true; StatusBar1-> SimpleText = "listening ..."; btnlisten-> Enabled = false; btnconnect-> Enabled = FALSE; ---- When the user presses the "Connection" button, the program pops up a query box, requires the user to enter the host name of the server to connect, and then establish a connection. Void __fastcall tform1 :: btnConnectClick (IF ("Connect to Server", Enter Server Address: (IF) {if (Server.Length ()> 0) {ClientSocket1-> Host = Server ClientSocket1-> Active = true; btnlisten-> enabled = false; btnconnect-> enabled = false; btndisconnect-> enabled = true;}}} ---- When the user proposes a connection request, the client triggers an oncreate event. The program first displays the connection information in the status bar, and then the MEMO2 that displays the contents of the other party is emptied, ready to start talking. Void __fastcall tform 1 :: ClientSocket1Connect (TCUSTOMWINSOCKET * SOCKET) {statusbar1-> simpletext = "Connect to:" Server; Memo2-> lines-> clear (); ---- The onaccept event is triggered after the server accepted the customer's request, and set the variable ISSERVER of the flag server side in this event handler to True and prepare to start talking. void __fastcall TForm1 :: ServerSocket1Accept (TObject * Sender, TCustomWinSocket * Socket) {Memo2-> Lines-> Clear (); IsServer = true; StatusBar1-> SimpleText = "connection to:" Socket-> RemoteAddress;} ---- After establishing the connection, the two sides can enter the conversation content in MEMO1 to start talking. After pressing the Enter key, send the text in the line. The Connections property of the server-side Socket returns an array that consists of a server currently active. void __fastcall TForm1 :: Memo1KeyDown (TObject * Sender, WORD & Key, TShiftState Shift) {if (Key == VK_RETURN) {if (IsServer) ServerSocket1-> Socket-> Connections [0] -> SendText (Memo1-> Lines-> Strings [Memo1-> Lines-> count-1]); else clientsocket1-> socket-> sendtext (memo1-> lines-> strings [memo1-> lines-> count-1]);}} ---- In this case, we use non-blocking transmission mode, when one of them is written, the other will trigger an OnRead event (client) or onclientRead event (server side & ---- in this case Using a non-blocking transmission mode, when one of them is written, the other will trigger an OnRead event (client) or an onclientRead event (server side). The handler of these two events is just added to MEMO2. Behind. Memo2-> lines-> add (socket-> receivetext ()); ---- If you click the "Dispenser" after the user is established, disconnect the client and server connection, the server side will trigger OnClientDisconnect event, the client triggers the onDisconnect event, then the server should go back to the listening state, waiting for the user's connection; and the client will return to the status before the connection, wait for the user to establish a connection again, if there is more than one server , you can choose to connect to other servers void __fastcall TForm1 :: btndisconnectClick (TObject * Sender) {ClientSocket1-> Close ();}. void __fastcall TForm1 :: ServerSocket1ClientDisconnect (TObject * Sender, TCustomWinSocket * Socket) {StatusBar1-> SimpleText = "listening ...";} void __fastcall TForm1 :: ClientSocket1Disconnect (TObject * Sender, TCustomWinSocket * Socket) {btnlisten-> Enabled = true; btnconnect-> Enabled = true; btndisconnect-> Enabled = false; StatusBar1-> SimpleText = ""; ---- In addition, the client should also increase the error capture mechanism, which can feed back user feedback when the user enters invalid server name or server side is not in the listening state. void __fastcall TForm1 :: ClientSocke t1Error (TObject * Sender, TCustomWinSocket * Socket, TErrorEvent ErrorEvent, int & ErrorCode) {StatusBar1-> SimpleText = "Could not connect to:" Socket-> RemoteHost; ErrorCode = 0;} Get application icons with C Builder Now, there is a large number of shared software or free software on the icon, and there are many very easy to use, and it is convenient. But after all, it is someone else, which is always used, and if you like to program, why not do it yourself! To do it, you will do it, and there is a visualized cutlery - C Builder 4.0, you want to be very simple. First start C Builder, create a new project, place a Button control on the form, an image control, and an OpenDialog control, and their names do not have to be changed. Double-click the Button control, write the following code: if (OpenDialog1-> Execute ()) { Filename = Opendialog1-> FileName; Hicon Hicon; // Total = (int) extracton (form1-> handle, filename.c_str (), -1); ICon = New ticon (); Hicon = Extracticon (Form1-> Handle, FileName.c_STR (), 0); Icon-> Handle = HICON; Icon-> Savetofile (TempFile); Image1-> Picture-> loadFromfile (TempFile); } Among them: FILENAME, TEMPFILE, ICON defines in its header: Ansistring TempFile, FileName; TICON * ICON; In this way, the first icon of your selected program is displayed in the Image control. The Windows API Extractic is used to get the chart, so it can only get the icon of the executable, if you want to get an icon of any file, you can call the Windows API's SHGETFILEINFO function to complete the task that ShgetfileInfo can complete There are a lot, and the specific usage can be found in the Win32 help file. BiG5 to GB conversion technology Because there are too many quantities, it is different from the English using ASCII code, which uses two bytes to represent. By calculating these two bytes, we can get the location of the Chinese characters in the Chinese word library. Read several bytes of this location to get dot matrix information indicating this Chinese character. With this information, you can display the Chinese characters in DOS or Windows, respectively. In fact, saved in a text file is two byte encodings corresponding to each Chinese character, and the display problem is automatically resolved by the Chinese operating system. Chinese character encoding is not uniform, we use the GB code, and the Taiwan area is BIG5 code. The BIG5 code file is saved is the corresponding BIG5 encoding of Chinese characters. The GB code file is saved in the GB code file (this is the origin of "garbled phenomena"). Therefore, the key to the conversion work is that there is a code table file that records each BIG5 encoding corresponding GB encoding. The first step to make the code table file BIG5 code encoding rule is this: Each Chinese character consists of two bytes, and the first byte ranges from 0x81-0xfe, a total of 126 species. The range of the second byte is 0x40-0x7e, 0xa1-0xfe, a total of 157 species. That is, 126 * 157 = 19782 Chinese characters can be defined using these two bytes. Part of these Chinese characters is commonly used, such as one, Dan, which is called common words, and its BIG5 code is 0xA440-0XC671, a total of 5401. More unused words, such as abuse, adjust, we call the common words, range from 0xc940-0xf9fe, a total of 7652, and the rest is some special characters. The principle of making code table files is this: first write all BIG5 encodes into a file, then use the software with BIG5 code to GB code conversion function, such as earth village, Oriental express, four-way persons, convert files to GB code file, you get the code table file. The following source program writes all possible BIG5 encoding (0xA100-0XFEFF) into the file "Table.txt". // Turbo C 3.0 #include // Turbo C 3.0 #include ---- When you are internetnowdrough in a Windows environment, have you noticed that there is an animation icon on the task bar on the right foot of the screen? It flashes flash, the image indicates that the network is transmitting data at this time. There are a lot of articles about the taskbar icon programming, but how can we prepare a moving icon? It is more convenient to implement in C Builder. ---- The basic programming idea is: Send a specific message in the specified time interval to make the taskbar icon to form an animation effect by setting the Timer Clock Control to send a specific message within a specified time interval. The implementation method is to load several image controls in the application's form, allowing them to load the corresponding drawings, and several graphs are continuously displayed in sequence, they form an animation. ---- Here, we use a door switch animation to do an example, put a Timer control on the form, two image, load "open" and "closing" two pictures. Start join the code. ---- Application must notify the task bar to add, delete, and modify the icon with the Means to send messages. Send messages must call Shell_Notifyicon. Its original shape is: WINSHELLAPI BOLL WINAPI Shell_NotifyiCon (PointifyCondata PnID); The first parameter dWMessage is a flag that sends a message, you can choose the NIM_ADD / / Task Bar Notification area Add Icon NIM_DELETE // Remove the icon NIM_MODIFY // Notification Task Bar Notification Area Modify Icon Compose a message transmission function TrayMessage bool __fastcall TForm1 :: TrayMessage (DWORD dwMessage) {NOTIFYICONDATA tnd; PSTR pszTip; pszTip = TipText (); tnd.cbSize = sizeof (NOTIFYICONDATA); // size of the structure tnd.uCallbackMessage = MYWM_NOTIFY; // Custom callback message, declare Tnd.hwnd = Handle; // accept the window handle TND.UID = IDC_MYICON; // icon flag number tnd.uflags = nif_tip; // specify the following three Which of the parameters contains valid data if (dwMessage == nim_modify) {Tnd.hicon = (hic) iconhandle (); // acquire the icon handle if (psztip) LSTRCPYN (Tnd.sztip, psztip, sizeof (tnd.sztip); Else Tnd.sztip [0] = '/ 0';} else {tnd.hicon = NULL; TND.SZTIP [0] = '/ 0';} return (shell_notifyicon (dwmessage, & tnd));} Function hicon __fastcall tform1 :: iconhandle (void) {if (n == 1) {return (image1-> picture-> icon-> handle); // n is global variable, 1 is display image1, 0 is image2} Else {RETURN (Image2-> Picture-> icon-> Handle);}} The icon status conversion function Void __fastcall tform1 :: ToggleState (void) {if (n == 1) // n is an icon handle lock, is a global variable, 1 is display image1, 0 is image2 {n = N-1;} else {n = n 1;} TRAYMESSAGE (NIM_MODIFY); // Send Icon Transform Message} To prepare a code for the Timer control, set its INTERVAL attribute to 1000, that is, the timer responds once every second. Type the code for the ONTIMER event: Void __fastcall tform1 :: timer1timer (TOBJECT * Sender) {ToggleState ();} ---- Due to limited space, only the basic part of the code, the implementation of other functions, such as closing the program, open the window, etc., relatively simple, not described. When the program is running, you will see a movie icon on the top right corner taskbar on the screen. Is it very interesting, let's make a favorite. TForm First, let the window always set to fsstayontop values at the forefront form of FormStyle property. Second, the dynamic calling window Form In the default, the window generated by the File / New Form is added to the window in the document with "Auto Create" features. That is, only the order is running, the window is stored in memory, and it is not to be called when it is. A window with this characteristic is generally suitable for the condition of the window property than being fixed, and is often called. The advantage is that the speed is fast, the shortcomings are occupied memory. In the actual sequence design, there will be a large amount of a pair of dialogue functionality, which are used to display the status or input information, and it is only necessary to transfer it in the program, and it is completed, there is no need for a resident memory. At this point, you can move the corresponding form in the "Auto - Create Forms" by selecting Project / Options / Forms, such as Form1, with the ">" box, and call the window in the program. In the body, add the following statement: tform1 * myform = new TFORM1 (this); MyForm-> showModal (); DELETE myForm; The Window Form1 is only transferred to memory only when it is needed, and the memory is completed, that is, use the delete clear memory. This can reduce the occupation of memory resources. Third, the method of all the calendar windows should visit or modified the controls on the window, the method is very simple, with TEDIT as an example: Edit1-> Text = ""; Edit2-> Text = "" However, there are ten controls like Edit1 on the windows. You need to enter the same initialization, and use the square method to enter a place, you will not be numb! There must be a method of holding a centralized parallel control. Before you introduce the method, let me first solve the component Form's Components and Controls attributes. See Table 1. Table I Property Type Description ComponentCount INT currently the total number of controls on Form Components Tcompont * Currently Form to point to arrays of all controls Currently, Form points to array of all controls ControlCount Int currently have the total number of controls on a single sub-area on a sub-area on the Form. Currently Form points to array of all controls on a sub-area Take the picture one as an example (Figure), FORM1's ComponentCount = 6, while panel1's controlCount = 4., Middle: array object Components [0] panel1 Components [1] label1 Components [2] Edit1 Components [3] label2 Components [4] Edit2 Components [5] Button1 Array object Controls [0] label1 Controls [1] Edit1Controls [2] label2 Controls [3] Edit2 The code below has completed the initialization of TEDIT controls on Panel1. The reader can be changed slightly, you can travel throughout the calendar. There is a small skill in this, and we put the controls that need to be initialized in a panel1, which is easy to score with the control area that does not require the initialization. Ansistring namestring = "tedit"; for (int i = 1; i { TEDIT * P = Dynamic_cast P-> Text = ""; } Fourth, irregular window 1. In the window definition, add hrgn hwndrgn; 2. In the TForm :: OnCreate () message function, add the following code: hwndRGN = :: CreatellipticRGN (0, 0, width, height); :: setWindowRgn (hwndrgn, True); 3. Setting the attribute of TFORM is no title, no border. 4. Compile the application to see an elliptical window. Five, MDI Form 1.Application-> Createform (__ classid (tjcginput), & jjcginput; It is not necessary to use the statement that uses the FORM to display it. 2.Form's OnClose event must be released by the following statement: void __fastcall tmdichild :: formclose (Tobject * sender, tclosection & action) {action = cafree; Create shortcuts with BCB in Windows desktop The API provides a COM interface called ISHELLLINK Allows us to create shortcuts. To create shortcuts at the desktop, we create an ishellLink object, set its properties, then save this Link to the Desktop directory. The following example code demonstrates how to create a shortcut. In this example, this shortcut is saved in the C: / Drive directory. / / -------------------------------------------------------------------------------------------- ---------------------- Include Void __fastcall tform1 :: button1click (TOBJECT * Sender) {if (OpenDialog1-> Execute ()) CreateShortcut (OpenDialog1-> filename);} //---------------- -------------------------------------------------- - void TForm1 :: CreateShortCut (const AnsiString & file) {IShellLink * pLink; IPersistFile * pPersistFile; if (SUCCEEDED (CoInitialize (NULL))) {if (SUCCEEDED (CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void ** ) {plink-> setpath (file.c_str ()); PLINK-> SetDescription ("WOO HOO, LOOK AT HOMER's Shortcut); PLINK-> setShowcmd (SW_SHOW); if (succeeded); (IID_IPersistFile, (void **) & pPersistFile))) {WideString strShortCutLocation ( "C: //bcbshortcut.lnk"); pPersistFile-> Save (strShortCutLocation.c_bstr (), TRUE); pPersistFile-> Release ();} pLink -> Release ();} Couninitialize ();}} // -------------------------------------------------------------------------------------------------------------- ----------------------------------- The above example is just to save the shortcut file to the C: / Drive directory Next, but not saved to the Desktop directory. To make the shortcut appear on the desktop, you only need to save the shortcut file to the Desktop directory. First we have to find Windows's Desktop directory, see Judging the section of Windows Desktop and related directories. Once we know the directory where Desktop is located, we can save the shortcut file to the Desktop directory. Then Windows can display the shortcut icon on the desktop. Here is an improved example: / / -------------------------------------------------------------------------------------------- ---------------------- void TForm1 :: CreateShortCut (const AnsiString & file) {IShellLink * pLink; IPersistFile * pPersistFile; LPMALLOC ShellMalloc; LPITEMIDLIST DesktopPidl; char DesktopDir [ MAX_PATH]; IF (Failed (SHGETMALLOC (& shell Malloc)) Return; IF (Failed (SHGETSPECIALFOLDERLOCATION) Return; & desktoppidl)) IF (! ShgetPathFromidList (Desktoppidl, Deskdir) {shellmalloc-> free (desktoppidl); shellmalloc-> Release (); return;} ShellMalloc-> Free (DesktopPidl); ShellMalloc-> Release (); if (SUCCEEDED (CoInitialize (NULL))) {if (SUCCEEDED (CoCreateInstance (CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) & pLink))) { PLINK-> setPath (file.c_str ()); PLINK-> SetDescription ("WOO HOO, LOOK AT HOMER's Shortcut"); PLINK-> setShowcmd (sw_show); IF (succeeded (plink-> queryinterface))) { WideString strShortCutLocation (DesktopDir); strShortCutLocation = "//bcbshortcut.lnk"; pPersistFile-> Save (strShortCutLocation.c_bstr (), TRUE); pPersistFile-> Release ();} pLink-> Release ();} CoUninitialize () ;}} // --------------------------------------------- ------------------------ Creating shortcuts in a mud that is not trapped in COM includes some use of COM. Don't let you fall into the complexity of COM. COM is just a way to create and use the object. In this example we can consider not using COM but use equivalent C technology. COM CODE C psuedo-equivalent ishelllink * plink; tshelllink * link; ipersistfile * ppersistfile; tpersistfile * persistfile; TPERSISTFILE Coinitialize (); CocreateInstance (clsid_shelllink, link = new tshelllink; null, clsctx_inproc_server, IID_IDLLINK, (Void **) & plink) PLINK-> setPath (file.c_str ()); link-> setpath (file.c_str ()); plink-> setshowcmd (sw_show); link-> setshowcmd (sw_show); PLINK-> Queryinterface (IID_IPERSISTFILE PERSISTFILE)) Dynamic_cast PPERSISTFILE-> Save ("c: //", true); persistfile-> save ("c: //"); PPERSISTFILE-> Release (); delete persistfile plink-> release (); delete link; Couninitialize (); Magnetic area First, the previous DOS version is read, write, format the first magnetic zone of the 0th track, the program is approximately as follows: Char buffer [512]; Reg.x.dx = 0; / * for drive a * reg.x.cx = 0x0001 / * for boot sector * / reg.x.bx = fp_off (buffer); SREG.ES = fp_seg (buffer); resg. x.ax = 0x0201; / * 02 for read, 03 for write, 05 for format * / int86X (0x13, ®, ®, & SREG); then converted to call DeviceIocontrol under Windows to format, read, write Magic Rails, Dioc_registers This structure is also INT21, which is also INT21, but Windows is also formatted, but it is also available in Windows. L # pragma pack (push, 1) struct dioc_registers {dword reg_ebx; dword reg_edx; dword reg_ecx; dword reg_eax; dword reg_edi; dword reg_esi; dword reg_flags;}; #pragma pack (POP) SDISKIMAGEINFO-> HDEVICE = :: CreateFile (".// Vwin32", 0, 0, null, 0, file_flag_delete_on_close, null); if (sdiskimageInfo-> hdevice == invalid_handle_value) brunnext = false; // reset floppy disk reg.reg_ebx = 0; reg.reg_eax = 0x0000; // ioctl for block def.reg_edx = sdiskimageInfo-> driver; reg.reg_edi = 0; reg.reg_esi = 0; reg.reg_flags = 0x0001; // Assume Error (Carry Flag Is Set) dwresult = :: Deviceiocontrol (sdiskimageInfo-> HDEvice, vwin32_dioc_dos_int13, ®, sizeof (dioc_registers), ®, sizeof (dioc_registers), & cb, 0); // seek floppy reg.reg_ebx = 0; reg.reg_eax = 0x0c00; // ioctl for block def.reg_ecx = (sdiskimageInfo-> nc << 8) | sdiskimageinfo-> ns; reg.reg_edx = (sdiskimageInfo-> NH << 8) | sDiskImageInfo-> Driver; reg.reg_EDI = 0; reg.reg_ESI = 0; reg.reg_Flags = 0x0001; // assume error (carry flag is set) dwResult = :: DeviceIoControl (sDiskImageInfo-> hDevice, VWIN32_DIOC_DOS_INT13 ,®, SizeOf (Dioc_registers), ®, Sizeof (Dioc_registers), & CB, 0); // Read Floppy R_CreateDiskImageFile: reg.reg_EBX = 0; reg.reg_EAX = 0x0200 | 0x01; // IOCTL for block devices reg.reg_ECX = (sDiskImageInfo-> nC << 8) | sDiskImageInfo-> nS; reg.reg_EDX = ( SDISKIMAGEINFO-> NH << 8) | SDISKIMAGEINFO-> Driver; reg.reg_ebx = (dword) & m_buf; reg.reg_edi = 0; reg.reg_esi = 0; reg.reg_flags = 0x0001; // Assume Error (carry flag set ) dwResult = :: DeviceIoControl (hDevice, VWIN32_DIOC_DOS_INT13, ®, sizeof (DIOC_REGISTERS), ®, sizeof (DIOC_REGISTERS), & cb, 0); if (! dwResult || (reg.reg_Flags & 0x0001)) {} I / O port Realization of reading and writing The readers of the thin heart will find that C Builder is no longer supported by InportB (), Outportb () a class I / O port read and write instruction. It is accurately that in the Windows environment, Borland C only supports the port operation of the 16-bit application program, and the port operation of the 32-bit application program is no longer supported, and the program from C Builder is 32-bit. I personally, this is the defeat pen of C Builder. Because of the PC, I / O address space and memory address space are all independent. Look at Delphi, don't you realize an interview with the I / O port through the port array? Can't make it clear? C Builder does not provide a similar mechanism? The following functions are written from the Internet. After passing through, it can be read from the I / O port under the Windows95 environment. Readers can use it for use. Void Outportb (Unsigned Short Int Port, Unsigned Char Value) { // Mov EDX, * (& port); __emit __ (0x8b, 0x95, & port); // Mov al, * (& value); __emit __ (0x8A, 0x85, & Value); // Out DX, Al; __emit __ (0x66, 0xee); } Void Outportw (Unsigned Short Int Port, Unsigned Short Int Value) { // Mov EDX, * (& port); __emit __ (0x8b, 0x95, & port); // Mov AX, * (& value); __emit __ (0x66, 0x8b, 0x85, & value); // OUT DX, AX; __emit __ (0xef); } Unsigned char inportb (unsigned short int port) { Unsigned char value; // Mov EDX, * (& port); __emit __ (0x8b, 0x95, & port); // in Al, DX; __emit __ (0x66, 0xec); // Mov * (& value), Al; __emit __ (0x88, 0x85, & value); Return Value; } UNSIGNED SHORT INT INPORTW (Unsigned Short Int Port) { UNSIGNED SHORT INT VALUE // Mov EDX, * (& port); __emit __ (0x8b, 0x95, & port); // in AX, DX __emit __ (0xed); // Mov * (& value), AX __emit __ (0x66, 0x89, 0x85, & value); Return Value; } Inspection mouse position For example, the mouse position is detected by a trigger event source of a timer TIMER1. Void __fastcall tform1 :: Timer1Timer (TOBJECT * SENDER) { TPOINT PT; GetCursorpos (& PT); Label1-> CAPTION = "(" INTTOSTR (PT.x) ") (" INTTOSTR (PT.Y) ")" } Make Win32 application program jump into the zero layer The public is known, and the zero ring (RING0, the highest level) and the three ring (RING3, the highest level) and the three ring (RING3, minimum level) are used in the Win32 On Intel X86 system of Windows95 / 98. In general, it is running under RING3, which is subject to strict "protective", which can only be used in torque. If we want to make some system-level operations, such as using such as "MOV EAX, CR0" in embedding, or call some essential system services (such as BIOS, DPMI services) as in DOS, "INT XX ", Will cause" illegal operation ". But this ability is not less than, when you come to this, Microsoft will write a VXD. VXD big home has been smelling, in VXD, not, but can execute the CPU's instructions, and can call the VMM (virtual machine tuner) and other VXDs. The most qualitative due to this ability is in its operation in Ring0, the same level as the system core. But it is the complexity of its system, the uncomfortable development tool is not easy to help the documentation, so that Microsoft has ranked a large number of proceedings and competition. WDM will also be a nightmare for WIN95 programming in Windows2000 (Windows 98, also starting). It is necessary to solve the WINDOWS NT core drive model. ---- Is there a simple manner? We can make a general WIN32 application program to run under Ring0, from the power of VXD? The answer is willing to pay. Next, I will tell this skill, there is a basic knowledge of Intel X86 protection model, please see the book. ---- First first technique based on the next reason, --- First, SIDT command (the interrupt descriptor table register IDTR - -64 bit wide, 16 ~ 47bit There is an interrupt descriptor table IDT base address - "Not the privileged directive, that is, We can execute the instruction in Ring3, to get the iDT base address, to modify the IDT, add a interrupt gate to place our interrupt service, once this interrupt is generated in the RING3 program, the VMM calls this interrupt service program, and this interrupt service The program is running under RING0. This is not often similar in DOS. ---- II, the Windows95 Win32 application runs a segment mapped to all 4G memory, the selected child is 0137h, and the VXD in RING0 runs in another paragraph that maps to all 4G memory, select sub-028h, these two In addition to the access rights decided by the selection, there is no difference, the same offset in each segment corresponds to the same linear address. The interrupt service program in the Win32 application program can be subjected to the VMM address in RING0 in the range of RIN 32 applications. . ---- This is a Win32 Console Program (control desk application program), although it looks like a real model DOS program in the DOS basket, it is the real price of the goods in the Win32 program under RING3. Create a Win32 Console Program project with Visual C 5.0 AppWizard, add the .cpp file, compile. #Include #include #include #include // If there is no DDK with the overline, these statements demonstrate DWordlong IDTR, SavedGate; Word Ourgate [4] = {0,0x0028,0xee00, 0x0000}; // Interrupt door descriptor format is as follows: DWORD _EAX, _ECX, _CR0; Word VMMVER; HVM SYSVM; Void Nothing () {// used to test call in ring0 sysvm = get_sys_vm_handle ();} Void __declspec (naked) Ring0Proc (void) // Interrupt routine, running in Ring0 {_ASM {MOV _EAX, EAX // MOV_ECX, ECX // MOV EAX, CR0 // Test Ring3 privilege MOV _CR0, Eax //} VMMCALL (GET_VMM_VERSION); // Call the VMM service _ASM {MOV VMMVER, AX} Nothing (); // Test in the interrupt routine running in RING0 _ASM IRETD / / interrupt return, with Real mode programming no essential difference} void main () // main program {_ASM {MOV EAX, OFFSET RING0PROC MOV [oorgate], AX // Address SHR EAX, 16 // Fill in the new interrupt door MOV [ Ourgate 6], AX // Descriptor SIDT FWORD PTR IDTR // Removes the contents of the interrupt descriptor table register (IDTR) MOV EBX, DWORD PTR [IDTR 2] // Remove Interrupt Description Table (IDT) Base Add EBX, 8 * 9 // Computing INT 9 The address of the descriptor should be placed. INT9 is because it does not occupy MOV EDI, OFFSET SAVEDGATE MOV ESI, EBX MOVST SavedGate Mov ESI, EBX MOVSD // in Win32 Protection Mode to save the original INT 9 descriptor to recover MOV EDI, EBX MOV ESI, OFFSET OURGATE MOVSD // Replace the original medium-breaking door description Movsd // to install the interruption service MOV EAX, 0x6200 // Test if the data placed in Eax is correct to Ring0 interrupt MOV ECX, 0 // to test the data placed in ECX to be correct to Ring0 interrupt MOV ECX, 0 // It is used to test whether the data placed in ECX is correct to Ring0 interrupt // because many VXD services use this two register pass parameter int 9H // artificial trigger interrupt, usually protect error Blue screen or illegal exercises // Box, now the // interrupt service routine is installed, the interrupt service routine will be called in RING0 in RING0. - -Ring0Proc MOV EDI, EBX MOV ESI, OFFSET SAVEDGATE MOVSD // Restore the original interrupt door descriptor MOVSD} Cout << "cr0 =" << _ cr0 <} _getch (); if (0 = "= _ getch ()" while ( _kbhit () = "= 0);" do {} continue.? < How to get MEMO's rows and columns Create a new application, add two TLABEL components on the form form1 named Label1, label2; add two TButton components named Button1, Button2; Add a TMEMO component named MEMO1. Then add the following code in the code editor. void __fastcall TForm1 :: Button1Click (TObject * Sender) {Label1 → Caption = SendMessage (Memo1 → Handle, EM_LINEFROMCHAR, -1,0) 1;} void __fastcall TForm1 :: Button2Click (TObject * Sender) {Label2 → Caption = Memo1 → SELSTART-SENDMESSAGE (Memo1 → Handle, EM_LINEINDEX, -1, 0) 1;} This method is equally applicable to RicheDit. Use sockets Use the Sockets Socket control to create an application that uses TCP / IP and related protocols to communicate with other systems. Using Sockets, you can read and write other machines connected through it without worrying about the details of the actual network software. Sockets provides a connection based on TCP / IP protocol. In addition to this, you can work well, in other related protocols, such as Xerox Network System (XNS), Digital's Dec Net, or Novell's IPX / SPX family. C Builder provides you write a web server or a client application to read and write other systems. A service or client program is usually focused on a single service such as Hypertext Transfer Protocol (HTTP) or File Transfer Protocol (FTP). Using Server Sockets, an application can provide one of these services to connect to a client that wants to use the service. Client Sockets allows an app to use a service application for this service using one of these services. Use Sockets to write applications, you must understand the following knowledge: 1. Services When you need to write network services or client applications, Sockets provides a joining. For many services, like HTTP or FTP, third-party service providers provide these services have been quite valid. Some even bundled with the operating system, so you can write it yourself. However, when you want more control services, if you want your application to communicate with network communications, or when there is no service to provide your special service, you may want to build your own service or customer. application. For example, when working in Distributed Data Sets, you may want to write a layer of communication with other system communications for the database. Want to use sockets to implement a service, you must understand: 1. Service Agreement Before you write a network service or customer program, you must understand what service will be provided or used by your app. Your web application must support the standard protocol of many services. If you are standard services such as HTTP, FTP write network applications, or Even Finger or Time, you must first understand the protocols used in communication with other system. Special Service Details You must see the documentation provided or used. If your application provides a new service to communicate with other system, the first step is to design a communication protocol for the server and client of this service. What information will be sent? How to organize this information? How do I encode this information? Application communications often, your network server or client application provides a layer of services used between network software and an application. For example, an HTTP service site provides content and answers between the Internet and a Web service application for HTTP request information. Provide an interface between Sockets between your web app (or customer application) and network software. You must provide an interface that is used in your application and intercom. You can copy the standard API provided by third-party service providers, or you can design and release your own API. 2. Understand the service and port many standard services are associated, specified port numbers. When performing a service, you can consider a port number for your service. If you implement a standard service, Windows Socket Objects provides some ways to let you look for a port number for your service. If you provide a new service, on a Windows 95 or NT machine, you can specify a associated port number for your service in the file service. For more information on Services file, please see Microsoft's Windows Sockets documentation. Second, the Socket connection type Socket connection can be divided into three basic types, which reflects how to start connecting and local Socket connections. These three types are: 1. Client connection client connection is a local system's client socket connection with a server Socket on a remote system. The client connection begins by the client socket. First, the client socket must describe the server socket it wants to connect. Then the client socket looks for the server Socket, which is required to connect when the server is found. The server Socket may not complete the correct connection. Server Sockets maintains a client request queue and completes the connection when they have time. When the server socket accepts the client connection, the server socket will send a complete description to the client Socket it wants to connect, and the client's connection is complete. 2. Listening to the connection server Socket does not locate the client, instead, they form a passive, "semi-connected" state, listen to the request from the client. The server sockets form a queue that stores the connection requests they have heard. This queue records the client connection request as they have been connected. When the server Sockets agrees that the client connection request, it forms a new Socket to connect to the client, so this listening connection can keep the open state to allow other client requests. 3. Server connection When listening to the Socket agrees a client request, the server side Socket forms a server connection. When the server is agreed to connect, send a server Socket description to the client to complete the connection. This connection is confirmed when the client socket receives this description. One but connected to the client's socket, the server connection cannot recognize the connection from one client. The same capabilities have the same capabilities to receive the same event type. Only the listening connection is different, it has only one single end. Third, Sockets Description Sockets makes your web application communicates with other systems over the network. Each Socket can be seen as a terminal point in the network connection. It has a specified address. * This system is running * The interface type it understands * The port used to connect to a complete Socket connection description, you must provide the address on both ends of the connection. Before you start a socket connection, you must complete the connection you want to get. Some information can be obtained from a system platform that is running in your application. For example, you don't need to describe a local IP address of a client Socket - this information can be obtained from the operating system. You must provide information about the type of Socket that you work. Client Socket must describe the servers they want to connect. Listening Server Sockets must describe the ports they provide a reactive server. A complete description of a socket connection terminal includes two parts: 1. IP address host is such a system that runs an application containing socket. You must describe the host to the Socket, complete this description by giving the IP address of the host. The IP address is a string with four numbers (Byte) values, in standard Internet dot paid. For example, 123.197.1.2 A simple system can support more than one IP address. IP addresses are often difficult to memorize and are easy to get wrong. A alive method is to use the host name. The host name is an alias of the IP address, which is the unified resource positioning (URLS) you often see. It is a string, including domain names and services. For example http://www.wsite.com Many internal networks are provided to the host's name, the system IP address is an Internetip address. On the Windows95 and NT machines, if a host name cannot be used, you can create an entry name for your local IP address (this local IP address should refer to the host IP address you want to connect "in the hosts file. . For more information on HOSTS file, please see the documentation of Windows Sockets. Server Sockets does not need to specify hosts. The local IP address can be read from the system. If the local system supports more than one IP address, the server Sockets will listen to the client request on all IP addresses. When a server Socket consents a connection, the client provides a remote IP address. Customer Sockets must specify the remote host by providing hostname or IP address. As a host name and IP address, a number of applications use a host name to specify a system. The host name is easy to remember and easy to check the typesetting error. Further, the server can change the system or the special host name associated with the IP address. Using a host name, you can allow the client to describe the abstract site by the host name, even if the host uses a new IP address. If the host name is unknown, the customer socket must specify the IP address used by the server system. By giving an IP address to specify the server faster. When you provide a host name, Socket must search for IP addresses related to this hostname before locating the server system. 2. Although the port number provides enough information to find enough information in the Socket connection, you usually need to specify the port number of that system. Without a port number, a system can only perform a single connection at the same time. The port number is the unique identifier that allows a standalone system to connect to a host that supports multiple connections at the same time, each connection must specify a port number. In web applications, the port number is a digital code for the server tool. There is a habit to listen to the client connected to their own fixed port numbers so that they can find the client sockets. Server Socket listens to the relevant port numbers for them. When they allow a client Socket connection, they create a separate socket connection that uses different dedicated port numbers. Through this method, you can continue to listen to the port number of the relevant service. Client Socket uses a dedicated local port number without other sockets to find them. They specify the port number of the server-side Socket they want to connect so they can find the server application. Often, this port number is indirectly specified by named service you want to connect. Fourth, use the Socket control C Builder to provide two socket controls, client sockets, and servers sockets. They allow your network application to connect to other machines and allow you to read and write information through this connection. Associated with each Socket control is a Windows Socket object, and their role of the terminal is an actual Socket connection. The Socket control uses the Windows Socket object to encapsulate the Windows Socket API call, so your application does not have to care about the details of the connection or manage Socket information. If you want to use the Windows Socket API call or custom connection details, the Socket control provides convenience, you can use the Properies, Events, and methods of the Windows Socket object. 1. Add a client Socket to your Form or Data Module to make your application a TCP / IP customer. Customer Sockets allows you to specify the server Socket you want to connect to and the services you want the server. One, you describe what you want, you can use the customer's Socket control to complete the connection service. Each customer Socket control uses a separate customer Windows Socket object to deck the client terminal in the connection. Use the customer sockets to go: A. Specify that you want to get the service customer Socket control has a digital Properties, allowing you to specify the server system and port you want to connect. You can specify the server system through the host name and use Host Property. If you don't know the host name, or if you care about find the speed of the server, you can specify the IP address of the server system, by using Address Property. You must specify one of the IP addresses and host names. If you are all specified, the customer's Socket control will use the host name. In addition to the server system, you must specify your customer socket to connect the port on the server system. You can use Port Property directly to specify the service port number. Or use the name you want to get directly in Service Property. If you specify port numbers and service names, the customer's Socket control will use the service name. B. Establish a connection Once you have completed the setting description description you want to connect to the properties of the server you want to connect, you can connect, by calling the OPEN method. If you want to automatically establish a connection when your application is started, set Active Property to TRUE when designing, and sets with Object Inspector. C. After obtaining information about the connection to the server Socket, you can use the customer Windows socket object related to your customers' Socket control to obtain information about the connection. Use Socket Property to access Client Windows Socket Object. Windows Socket Object has a Properties that allows you to determine the address and port number used by the clients and servers connected to the connected. When using a Windows Socket API called, you can use the SocketHandle Property area to get the Handle used by the Socket connection. You can use the Handle Property to access Windows to receive information from the socket connection. AsyncStyles property determines which information type is Windows Handle to be received. D. Close connection When you complete the communication want to close the socket connection, you can close the connection by calling the Close method. The connection may be turned off by the server. If this is this, you will receive a notification of an OnDisconnect event. 2. Add a server Sockets to your Form or Data Module to make your application a TCP / IP server. Server Sockets allows you to specify the service you want or you want to use to listen to the client request. You can use the server Socket control to listen and allow customer connection requests. Each server Socket control uses a single server Windows Socket Object (TSERVERWInsocket) to answer the connection in the server side. It usually uses a server customer WinODWS Socket Object (TSERVERCLIENTWINSOCKET) to answer each activity of the server and connect to the client Socket that is allowed. Use the server sockets to go: a. Specify port before you can listen to the customer request, you must specify a port to your listening service. You can use Port Property to specify this port. If your server application provides a standard service, this service uses a associated port associated with use. You can specify port numbers directly using Service Property. Using Service Property is a good idea to reduce errors when setting port numbers. If you specify both Port Property, you specify Service Property, and the service name will use the service name. B. Listening Customer Request Once you set your port number on the Server Socket control, you can listen to a connection by calling the Open method at runtime. If you want your application to automatically listen to the connection during startup, set the Active property to True by using the Object Inspector when designing. C. Connect to the client. They will automatically accept this request when the listening service Socket control receives a client connection request. The ONCLIENTCONNETC event will happen when you have received the notice. D. Get information about the connection one but your server socket opens the listening connection, you can use the server Windows socket Object associated with your server Socket control to obtain information about the connection. Use Socket Property to access Server Windows Socket Object.Windows Socket Object There is a property that allows you to find a customer socket connection to all active Customer Socket is allowed to be connected by the server Socket control. Use the Handle property to access the information received through the socket connection through the Socket. Each activity is connected to the customer app, and the customer Windows Socket Bject (TSERVERCLIENTWInsocket) is packaged. You can access all of these through the connection properties of Server Windows Socket Object. These Server Client Windows Socket Object Some properties allow you to decide which addresses and port numbers are used on both ends of the connection - Customer and Server Socket. When you use the Windows Socket API call, you can use the socketHandle property to get the Handle used for the Socket connection. You can use the Handle property to access the information from the Socket connection from the socket connection. The asyncStyles property determines which type of information will be received by Windows Handle. E. Close connection When you decide to turn off the listening connection, call the Close method. This will turn off all open, connect to the client application, and cancel any unconnected connection, then close the listening connection so that your service Socket control is not accepted any new connection. When the client closes their own independent connection to your Server Socket connection, you can get a message in the OnClientDisconnect event. 5. The response of the Socket event When using sockets Write an application, most work occurs in the Handler event of the socket control. When you start reading or writing via the socket connection, the OnRead and OnWrite events occur in the Non-Blocking Client Sockets. Sockets. Server Sockets (Blocking or Non-Blocking) Receives OnClientRead and OnClientWrite events. When the server ends a connection, the customer ScokeTs receives an onDisconnect event. When the client ends a connection, the server Socket receives an OnClientDisconnect. Event. In addition, client sockets and server-side sockets will have an error event when you receive an error message from the connection. Error event: Customer Sockets and Server Sockets usually generate an onERROR event when they receive from the connection When you go to an error message. You can write an onError event to respond to these error messages. This OneRror event handles information provides information about this error when you try to do what to do, and the error code provided by the error message. You can This error is responding to this error in OneRror event processing, and the error code is changed to 0 to avoid the socket produce an exception. When started and completed, the socket control usually receives an event number. If your application needs to change the process of the Socket start operation or start reading or writing through the connection, you will write an event handlers. Recover these Client Events and Server Events. A.Client Events When a customer socket opens a connection, the following events occur: 1. A ONLOOKUP event happens, it tries to locate the Server Socket. Here you can change Host, Address, Port, Service property to change you. Located servers. You can use the socket property to access the Client Windows Socket Object, and use its socketHandle property to call the Windows API to change the customer properties of the socket. For example, if you want to set the port number in the customer application, you must Do this before the Server Client connection. 2.Windows socket settings and initialization event notifications. 3. A OnConnecting event occurs when you find the Server Socket. In this event, Windows Socket Object can take advantage of the connection with the socket property The other end of the service socket. This is the first opportunity to get the port and IP address of the actual use to connect, which may differ from port or IP addresses you get when you agree to join the Socket. 4. Server agreed Connection request, client socket completes the connection. 5. When a connection is determined, an OnConnect event occurs. If your socket immediately begins to read or write, you should write an OnConnect event handler to see this. B. Server Events Server Socket Controls Connections by two: listening to the connection and connecting to the client application. Server Socket receives all events for both connections. When the listener is constituting the listening connection, the OnListen event happens. At this time you can get Server Windows socket object through the socket attribute. You can use its socketHandle property to change the socket, before the Socket opens. For example, if you want to limit Listening to the IP address used by the service, you can do it in this OnListen event handler. Events connected to the client When a server Socket agrees to a client connection request, the next event happens: 1. Server Socket generates an OnGetSocket event through Windows Socket Handle to the other end of the other end of the connection. If you want to provide yourself defined TServerClientWinSocket of descendant, you can create an event handler in the OnGetSocket, it will be used to replace TServerClientWinSocket. 2. a OnAccept event, send a new TServerClientWinSocket object to the event handler. this is the first point, when you use the TServerClientWinSocket Attributes to get information about the client of the end of the connected service. 3. If the service type is stthreadblocking, an OnGetThread event occurs. If you want to provide your own TSERVERCLIENTTHREAD subclass, you can build one in the OnGetThread event handle, it The TSERVERCLIENTTHREAD. 4. If the service type is stthreadblocking, a ONTHREADSTART event occurs when this thread starts to execute. If you want to perform any initialization, or call some Windows Socket API to start through the connection and write Previously, the ONTHREADSTART handle should be used. 5. When the client completes a connection, an OnClientConnect event occurs. If it is a non-blocking service, you may want to start reading or writing at this end via the socket. Six, through Socket Connections Read and write through sockets to other machines The reason is to read and write information through these connections. What information is what you want to read and write, or when you want to read and write? . Read and write via Sockets can be asynchronous, so there is no need to block other code execution in your web application. This is called Non-Blocking Connection. You can also pass the Blocking Connection, then your next line The execution of the code must wait until the read or write operation is complete. A.non-blocking connection, read and write is asynchronous, so there is no need to block other code in your web application. Create a non-blocking connection: 1. Set the clientType property in CTNONBLOCICKING. 2. Setting the serverType property in ServerType attribute is stnonblocking. When the connection is non-blocking, the other end of the connection is attempting to read or write this information to notify your Socket. Read and write operations Non-Blocking Sockets wants to read and write an operation event to notify you Socket by connecting to read or write. On the client sockets, you can make these events in the OnRead or OnWrite event handle. Reaction. On the server-side ScokeTs, these events can be reacted in the OnClientRead or OnClientWrite event handle. Windows socket object associated with the socket connection is used as a parameter in the read or write of the event handle. Windows socket object provides one Number of Methods allows you to read or write through the connection. Connect, read, use the ReceiveBuf or ReceiveText method. Using the ReceiveLength method, use the Recereength method to determine the number of bytes to the other end Socket (NUMBER OF BYTES). Connection is written through the socket, use SendBuf, SendStream, or SendText method. If you send information through the socket, you can use the SendStreamThendrop method. SendStreamThendrop method. SendStreamThendrop method After writing all the information will close the Socket connection It is able to read information from stream. If you use SendStream or SendStreamThendrop method, do not release Stream Object, Socket automatically releases this stream after the connection is over, Note: SendStreamThendrop will turn off a separate customer connection service instead of listening. B. Blocking Connections When you use the connection is blocking, your socket must be read or written through the connection, the passive waits will be sent from the Socket connection. When your connection ends change Use the Blocking Socket. For the client sockets, set the ClientType property to ctblocking to make a blocing connection. Based on your client application want to complete what, you may want to create a thread to complete the read or write operation so that your application can Continue to perform other threads, when it is waiting to be completed by the connection or write operation. For the server sockets, set the serverType property to stthreadBlocking to make a blocking connection. Because Blocking Connections is waiting through the connection to read or write information. Other code execution, the server Socket control typically generates a new execution thread to connect each client, when Servertype is set to StthreadBlocking. Many applications using the blocking connection are written using threads (Used Threads. Even if you don't use thread, you You may also want to use (use) TWinsocketStream to read and write. 1) using threads When you read or write using a Blocking Connection, the customer sockets will not automatically generate a new thread. If your client application doesn't have anything, This is exactly what you want. If your application includes a user interface, it also needs to respond to the user's operation, then you may want to generate a separate thread to read and write. When the server When Sockets forms a Blocking connection, they often generate independent threads to each client, so no customers need to wait until other customers complete through the connection or write. By default, server Sockets uses TServerClientThread objects to each. Connecting different threads. TSERVERCLIENTTHREAD object simulates OnClientRead and OnClientWrite events in a non-blocking connection. However, when listening to the socket, not a local thread (thread-local). If the customer requests frequent, you will want Establish your own TSERVERCLIENTTHREAD subclass to provide a safe thread to complete the read and write operation. When the client thread or writes server thread, you can use TwinsocketStream to do actual read and write operations. A) Write the client thread to write a thread to the client, define a new thread object, use the new thread object dialog box. Your new The thread object execute method's handle of the handle of the read / write operation can create a TwinsocketStream object, and then use it to read or write. Use your own thread to create it in the OnConnect event handle. About establishing and running thread For more information, please see Executing Thread Objects. Example: This example shows a client thread to send a write request to the server after the connection is determined. Void __fastcall tmyclientthread :: execute () {while (! Terminated && clientsocket1-> activ) // make sure connection is active {try {TWinSocketStream * pStream = new TWinSocketStream (ClientSocket1.Socket, 60000); try {char buffer [10]; GetNextRequest (buffer); // GetNextRequest must be a thread-safe method // write A Request to the Server Pstream-> Write (Buffer, Strlen (Buffer) 1); // Continue The Communication (EG Read a Response)} __finally {Delete pStream;}} catch (Exception & E) {if (E.ClassNameIs ( "EAbort")!) Synchronize (HandleThreadException ()); // you must write HandleThreadException}}} B) to write server-server connection thread by the thread TServerClientThread Delivery. Because of this, you cannot use the new thread object dialog. Replace, manual declaration your thread is as follows: Class Package TMYSERVERTHREAD: PUBLIC SCKTCOMP :: TSERVERCLIENTTHREAD {PUBLIC VOID __FASTCALL ClientExecute (void); Note that you will replace the Execute method with the overload clientExcute method. Execute the ClientExecute method must write a similar Execute method thread to the client connection. However, when you put a customer's Socket control from the control bar to your application to replace this Methods. Listening Services Socket Agree When a connection, the service customer thread must be built using the TSERVERCLIENTWInsocket object. This can take advantage of a common CientSocket property. In addition, you can use the HandleException this protected method, better you write your THREAD -SAFE exception operation. WARNING: Server Sockets caches the thread they use. Confident that the ClientExecute method performs some necessary initialization operations so that they do not cause unfavorable results at the end of the execution. When you use your thread, create it in the OnGetThread event handle. When you create a thread, set the createSuspended parameter to false. Example: This example shows a thread for an application service, this application is after the connection is determined by the client. Read request. (! Terminated && ClientSocket-> Connected) void __fastcall TMyServerThread :: ClientExecute () {while // make sure connection is active {try {TWinSocketStream * pStream = new TWinSocketStream (ClientSocket, 60000); try {char buffer [10]; memset (Buffer, 0, Sizeof (Buffer); IF (PStream-> Waitfordata (60000)) // Give The Client 60 Seconds to Start Writing {IF (pstream-> Read (Buffer, Sizeof (Buffer) == 0) ClientSocket-> Close (); // if can't read in 60 seconds, close the connection // now process the request} else clientsocket-> close ();} __finally {delete pstream;}} catch (...) {handleexception ();}}} C. When using TwinsocketStream When you implement a thread as a Blocking connection, you must determine that the Socket in the other end of the connection is ready to write or read. Blocking connection does not inform Socket When it is ready to write or read it. I want to see Whether the connection is ready, use the TwinsocketStream object .twinsocketStream provides a method to help adjust the selection of read or write operation time. Call the waitforData method to wait until the other end of the socket is ready to write. When the read, write, use TwinsocketStream, if read Or write operations fail within the specified time period, Stream will take timeout. This timeout is used as a result, the Socket application will not be paused, but constantly engage or write through a Dropped Connection. Note: You can't be TWinsocketStream in Non-Blocking connection How to hide the app under Windows95 / 98 Do not let it appear in the CTRL-Alt-Del dialog? A simple way to hide your app from the Ctrl-Alt-Del dialog is to go to the application's title. If the main window of a program is not headline, Windows95 does not put it in the CTRL-Alt-Del dialog. The best place to clear the title attribute is in the Winmain function. WinAPI Winmain (Hinstance, Hinstance, LPSTR, INT) {try {Application-> Title = ""; Application-> Initialize (); Application-> Createform (__ classid (tform1), & form1); application-> run (); Catch (Exception & Exception) {Application-> showexception (& Exception);} Return 0;} Another way is to call the RegisterServiceProcess API function Register the program into a service mode program. RegisterServiceProcess is a function that is related but no official files in kernel32.dll. There is no prototype instructions for this function in the MS SDK header file, but can be found in Borland Import Libraries for C Builder. Obviously, the main purpose of this function is to create a service mode program. The reason why it is obvious because it does not say anything about this function in MSDN. The following example code demonstrates how to hide your program from the Ctrl-ALT-Del dialog box under Windows95 / 98. // ------------------------------------------------------------------------------------------------_stdcall * pregfunction (DWORD, DWORD); class TForm1: public TForm {__published: TButton * Button1; private: HINSTANCE hKernelLib; pRegFunction RegisterServiceProcess; public: __fastcall TForm1 (TComponent * Owner); __fastcall ~ TForm1 ();}; // ----------- CPP File ---------------------------- #include "unit1. H " #define rsp_simple_service 1 #define rsp_unregister_Service 0 __fastcall TForm1 :: TForm1 (TComponent * Owner): TForm (Owner) {hKernelLib = LoadLibrary ( "kernel32.dll"); if (hKernelLib) {RegisterServiceProcess = (pRegFunction) GetProcAddress (hKernelLib, "RegisterServiceProcess"); if (RegisterServiceProcess) RegisterServiceProcess (getCurrentProcessid (), RSP_SIMPLE_SERVICE);}} __fastcall tform1 :: ~ tform1 () {if (hkernellib) {if (registerServiceProcess) registerServiceProcess (getCurrentProcessId (), Rsp_unregister_service; Freelibrary (hkernellib);}} // ----------------------------------------- -------- Note: There is no RegisterServiceProcess function under Windows NT. How to hide the application task icon First, see these terms. The system tray is a small box in the right corner of the task bar, and the application can display a small icon in the pallet. Task bars are toolbars that can be extended on the screen. It is where the program icon is located. To hide the task icon of the program, you can apply the showWindow function and pass it to the Application-> Handle window handle. ShowWindow (Application-> Handle, SW_HIDE); if you want the task bar icon to appear again, simply change sw_hide to sw_show. ShowWindow (Application-> Handle, SW_SHOW); Note: You can set the Visible property of the main window to hide it. Note: The task bar icon for hiding the window via ShowWindow is not lasting. Some movements will make the task bars icon. You can set the hidden application window to Tool Window to remove the program's task bar icon to avoid it again. Tool Windows never has a task bar icon. Make the application window a tool window has a side effect: it will not appear in the list when the user presses alt-tab. You can call the API function getWindowlong and SetWindowl to make the application window a Tool window. WinAPI Winmain (Hinstance, Hinstance, LPSTR, INT) { DWORD DWEXSTYLE = getWindowlong (Application-> Handle, GWL_EXSTYLE); DWEXSTYLE | = WS_EX_TOOLWINDOW; SetWindowlong (Application-> Handle, GWL_EXSTYLE, DWEXStyle); try {Application-> Initialize (); Application-> CreateForm (__ classid (TForm1), & Form1); Application-> Run ();} catch (Exception & exception) {Application-> ShowException (& exception);} return 0;} Write your own ping.exe program In a Windows system, we often use ping.exe to test the connectivity of the network. The implementation process of ping is simple. This command will trigger an IP layer to send a simple IP package, usually 32 bytes. After the goal receives this package, turn the source address and destination address, resend this package, of course, add some timeout mechanisms. In fact, we can also use NMecho controls in C Builder NetMaster to implement network connection detection. First define the following controls: Three EDIT controls: An IP address or domain name for receiving a remote host, a time for receiving a timeout mechanism for a user setting, an intended port number. Two RicheDit controls: A information for sending information to the remote host, one for receiving information from the remote host. Two Checkbox controls: Used to set the port number yourself. A Button Control: Used to perform a test. A STATUSBAR control: The status of the application is displayed. The program implements the code as follows: Void __fastcall tform1 :: Button1click (Tobject Sender) {// Set the standard TCP / IP attribute of the NMECHO control NMecho1-> Host = Edit1-> text; NMecho1-> timeout = start (edit2-> text); IF (CheckBox1-> Checked) NMecho1-> port = start (edit3-> text); Else NMecho1-> Port = 7; // Echo's default port number in TCP / IP Nmecho1-> ReportLevel = status_basic; NMecho1-> connection (); // Establish a connection Richedit2-> clear (); For (int i = 0; I // richedit1 is used to send information to remote host Richedit2-> text = richedit2-> text nmecho1-> echo (richedit1-> lines-> Strings [i]); NMecho1-> disconnect (); } Note: When calling the connect () method of the NMecho control, you should ensure that the connection has been established before receiving the data. When the Connect () method is called, if the user enters the domain address instead of the IP address, and the domain server successfully parses this domain name, the control of the onHostResoved event will trigger the control, in the process of this event, we will resolve successful messages Displayed to the user in the status bar. The specific implementation code is as follows: void __fastcall tform1 :: nmecho1HostResolved (tcomponent Sender) { Statusbar1-> panels-> items [0] -> text = "Host Resolved!"; } If the remote host entered by the user is incorrect, the ONINVALIDHOST event of the control will be triggered. In this event, the pop-up dialog requires the user to re-enter the IP address or domain name address of the remote host, and then try to reconstruct the server. The specific code is as follows: Void __fastcall tform1 :: nmecho1invalidhost (Bool && Handled) { Ansistring s; IF (INVAILID HOST! "," Specify A New Host: ", S)) { NMecho1-> host = s; Handled = True; } } After establishing a connection, the ONCONNECT event of the control is triggered. In this process, we will display the successful message to the user in the status bar. The specific implementation code is as follows: void __fastcall tform1 :: nmecho1connect (TOBJECT sSENDER) { Statusbar1-> panels-> items [0] -> text = "Echo Has Connected Host!"; } If after the Connect () method is called, the ONCONNECTFAILED event of the control is still not connected to the server at the timeout time, and the message we fails to the user in the process of this event. The specific implementation code is as follows: Void __fastcall tform1 :: nmecho1connectionfailed (TOBJECT SENDER) { ShowMessage ("Connection Failed!"); } In addition to NMECHO controls, the NETMASTER's NMDaytime, NMTIME is also implemented. The method is the same as NMecho controls, and the difference is NMDayTime and NMTIME these two controls do not need to first call the connect () method, and their connection to the server is automatically performed when using DayTimeStr, TIMESTR property. Prepare a service with C Builder under Winnt ---- Windows NT has a very important difference with Windows 9x, that is, Windows NT provides a lot of powerful service. These services can start from the start of NT, or allow users to start by the control panel, and can be stopped by the Win32 application. Even without the user login system, these services can also be executed. Many ftps, WWW servers and databases are in NT in the form of service, thereby achieving unattended. Even the latest version of the "hacker" program Back OrificE 2000 is also hidden on the service in the form of a service. Because Service is more complicated, many developers want to develop their own service but often. In view of this, then we will construct a new service from the head to the end, readers as long as they add their own code in the program, then you can easily have a self-service. Please let a few important functions before writing service: ---- 1. SC_Handle OpenScManager (LPCTSTSTSTSTSTABASENAME, DWORD DWDESIREDACCESS) ---- OpenSCManager function Opens the Service Control Manager Database on the specified computer. The parameter lpMachinename specifies the computer name, and if specified as the unit for the air. LPDATABASENAME is empty for the Service Control Manager Database name to be opened. DwdesiredAccess Specifies the permissions of the operation, can be one of the values below: ---- SC_Manager_All_Access // All permissions ---- SC_Manager_Connect // Allows to connect to Service Control Manager Database ---- SC_MANAGER_CREATE_SERVICE / / Allow to create a service object and join Database ---- SC_Manager_Enumerate_Service // Allows enumeration in Database Services ---- SC_Manager_lock // Allows to lock DATABASE ---- SC_MANAGER_QUERY_LOCK_STATUS / / Allow Query Database Blocking Information ---- The function is successful, returns a handle to the Service Control Manager Database, returns NULL. Note: Winnt manages all services through a database called Service Control Manager Database, so this database should be opened for any operation of Service. ---- 2. SC_Handle CreateService (sc_handle hscmanager, LPCTSTR lpServiceName, LPCTSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR lpBinaryPathName, LPCTSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCTSTR lpDependencies, LPCTSTR lpServiceStartName, LPCTSTR lpPassword) ---- CreatService function generates a new service. The parameter hscmanager is the handle of the Service Control Manager Database, returned by OpenScManager. LPServiceName is the name of Service, LPDisplayName is a service display name, DwdesiredAccess is access, this program with service_all_access. WSERVICEPE, specify the service type, in this program with service_win32_oen_process | service_interactive_process. DWStartType is the service launch method, this program uses self-start, ie DWStartType is equal to service_auto_start. DWERRORCONTROL Note What actions take when the Service is in the launch, this program uses service_error_ignore, and readers can be changed to other. LPBINARYPATHNAME indicates the path name of the Service ontology program. The remaining five parameters can be typically set to NULL. If the function call is successful, return this new service handle, and the null is returned. Corresponding to this function is DELETSERVICE (HService), which deletes the specified service. ---- 3. SC_Handle OpenService (sc_handle hscmanager, lpctstr lpserviceename, dword dwdesiredaccess) ---- OpenService function Opens the specified service. The parameter hscmanager is the handle of the Service Control Manager Database, returned by OpenScManager. LPServiceName is the name of Service, dwdesiredAccess is access to access, and its optional value is more, readers can see the SDK Help. The function call successfully returns the open service handle, and returns NULL. ---- 4. Bool StartService (SC_Handle HService, DWORD DWNUMSERVICEARGS, LPCTSTSTR * LPSERVICEARGVECTORS) ---- StartService function starts the specified service. The parameter hservice is a handle pointing to the service, returned by OpenService. DwnumServiceA is the number of parameters required to start the service. LPSZServiceArgs is the parameters required to start the service. The function is successful, returns true, and false is returned. ---- 5. Bool ControlService (sc_handle hservice dword dwcontrol, lpservice_status lpservicestatus) ---- Service program does not have a dedicated stop function, but uses the ControlService function to control the suspension of service, continue, stop, etc. The parameter dwcontrol specifies the issued control command, which can be the following values: SERVICE_CONTROL_STOP // Stop Service SERVICE_CONTROL_PAUSE // Pause Service SERVICE_CONTROL_CONTINUE // continue Service SERVICE_CONTROL_INTERROGATE // Query Service status SERVICE_CONTROL_SHUTDOWN // make ControlService call failure ---- Parameter LPServiceStatus is a pointer to Service_Status. Service_status is a more important structure that contains various information of the service, such as the current state, which control commands, and more. ---- 6. Bool QueryServiceStatus (sc_handle hservice, lpservice_status lpservicestatus) ---- The queryServiceStatus function is relatively simple, it queries and returns the status of the current service. ---- Preparing a service usually requires two programs, one is a service body, one is a control program for controlling Service. Usually the service body is a console program, and the control program is a normal Win32 application (of course, the user can be enabled by the control panel without the control program, stopping, but can not add, delete the operation.) ---- First, let's write the service body. For the service body, it is generally composed of three parts: main (), servicemain (), handler (), the source code of Main (): (Note: Due to the relationship of the space, most of the program is not Error handling, readers can add themselves) INT main (int Argc, char ** argv) {service_table_entry ste [2]; // A Service process can have multiple threads, this is the entry table of each // thread Ste [0] .lpServiceName = "WZService" ; // thread name Ste [0] .lpserviceproc = service; // thread entry address STE [1] .lpServiceName = null; // The last must be null ste [1] .lpserviceProc = null; startServiceCtrlDispatcher (ste); return } ---- Main () is the main thread of the service. When Servie Control Manager starts a service process, it is always waiting for this service to call the StartServiceCtrldispatcher () function. Main () as the main thread of this process should call StartServiceCtrlDispatcher as soon as possible after the program. StartServiceCtrlDispatcher () is not immediately returned after being called, connects the host's main thread to Service Control Manager, so that Service Control Manager will start, stop control commands to the main thread through this connection. The main thread played the role of a command transponder, it or calls handle () to process the stop, continue the control requirements, or generate a new thread to execute ServiceMain. StartServiceCtrlDispatcher () returned at the end of the service. ---- ServiceMain () is a true entry point for Service, must be properly defined in main (). The two parameters of ServiceMain () are passed by StartService (). The following is the ServiceMain () of source code: void WINAPI ServiceMain (DWORD dwArgc, LPTSTR * lpszArgv) {ssh = RegisterServiceCtrlHandler ( "WZSERVICE", Handler); ss.dwServiceType = SERVICE_WIN32_OWN _PROCESS | SERVICE_INTERACTIVE_PROCESS; ss.dwCurrentState = SERVICE_START_PENDING; // If the code of the user program is more (execution time is more than 1 second), it is set to service_ start_pending, and then set to service_running after the user program is completed. ss.dwcontrolsaccepted = service_accept_ stop; // indicates that the command currently accepts is a stop command. Ss.dwwin32exitcode = no_error; ss.dwcheckpoint = 0; ss.dwwaithint = 0; setServiceStatus (SSH, & SS); // must update the status of the service in the database at any time. Mycode (); // This can be put into the user's own code ss.dwServiceType = SERVICE_WIN32_OWN_ PROCESS | SERVICE_INTERACTIVE_PROCESS; ss.dwCurrentState = SERVICE_RUNNING; ss.dwControlsAccepted = SERVICE_ACCEPT_STOP; ss.dwWin32ExitCode = NO_ERROR; ss.dwCheckPoint = 0; ss.dwWaitHint = 0; SetServiceStatus (ssh, & ss); Mycode (); // This can also be put into the user's own code} RegisterserviceCtrlHandler () should be called immediately in ServiceMain () to register a Handler to deal with the control program or the control panel to the service's control requirements. Handler () is called to deal with the forwarder, the following is the source code of Handler (): Void WinApi Handler (DWORD OPCODE) {switch (opcode) {copy service_control_stop: // Stop Service mycode (); // can be put into it here User's own code ss.dwwin32exitcode = 0; s.dwcurrentState = service_stopped; // Put the current state of Service to stop ss.dwcheckpoint = 0; ss.dwaithint = 0; setServiceStatus (ssh, & ss); / must be updated at any time The status of the service in the database; Case Service_Control_INTERROGATE: SETSERVICESTATUS (SSH, & SS); / Must update the status of the service in the database in the database;}} ---- Well, the service body program is basically completed, we will then look at the service Control Program: ---- Control Program is a standard Window program, which mainly has four heads: Create Service, Delete Service, Start, STOP, which is used, delete, start, and stop service. Below is some of their source code: 1. Generation Service void __fastcall TForm1 :: CreateBtnClick (TObject * Sender) {scm = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (! Scm = NULL) {svc = CreateService (scm, "WZSERVICE", "WZSERVICE" , // Service name SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, // an automated way to start SERVICE_ERROR_IGNORE, "C: //ntservice.exe", // Service body program path, and the specific location must match NULL, NULL, NULL, NULL , NULL); if (SVC! = Null) ClosESERVICEHANDLE (SVC); ClosESERVICEHANDE (SCM);}} 2. Remove Service void __fastcall TForm1 :: DeleteBtnClick (TObject * Sender) {scm = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT); if (scm = NULL!) {Svc = OpenService (scm, "WZSERVICE", SERVICE_ALL_ACCESS); if (svc = NULL!) {QueryServiceStatus (svc, & ServiceStatus); if (ServiceStatus.dwCurrentState == SERVICE_RUNNING) // before deletion, stop this Service ControlService (svc, SERVICE_CONTROL_STOP, & ServiceStatus);. DeleteService (svc); CloseServiceHandle (svc ); // After deleting the service, it is best to call CloseServiceHandle} // to remove this entry from the database immediately. CloseServiceHandle (scm);.}} 3 Start Service void __fastcall TForm1 :: StartBtnClick (TObject * Sender) {scm = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT); if (scm = NULL!) {Svc = OpenService (scm, "WZ Service ", service_start); if (SVC! = Null) {StartService (SVC, 0, NULL); // Start Service ClosESERVICEHANDE (SVC);} ClosESERVICEHANDE (SCM);}} 4. Stop Service void __fastcall TForm1 :: StopBtnClick (TObject * Sender) {scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS); if (! Scm = NULL) {svc = OpenService (scm, "WZSERVICE", SERVICE_STOP | SERVICE_QUERY_STATUS) ; if (! svc = NULL) {QueryServiceStatus (svc, & ServiceStatus); if (ServiceStatus.dwCurrentState == SERVICE_RUNNING) ControlService (svc, SERVICE_CONTROL_STOP, & ServiceStatus); CloseServiceHandle (svc);} CloseServiceHandle (scm);}} How to automatically turn off Windows screen protection in C Builder ---- In actual programming applications, when the program needs to handle certain calculations with a longer time, this time may cause Windows to start screen protection, so that the process of the program will become relatively longer. So how do you automatically turn off the screen protection when running a program? ---- Windows sends a WM_SYSCOMMAND message to the activated programs before starting screen protection, and sets the WPARAM parameter of the message to sc_screensave. We can use the onMessage event of the Tapplication class in C Builder to handle this message from Windows. If you set the Handled parameter to TRUE after the received message, this response message value can prevent the screen protection. ---- The process of C Builder 4.0 is as follows: ---- 1, select File | New Application from the main menu to create a new empty project file. Then add a Label object on the FORN, set its CAPTION to "this program will turn off Windows Screen Protection". ---- 2, declaration of the member function processMessage in the program header file Unit1.h to the definition of TFORM1. class TForm1: public TForm {__published: // IDE-managed Components TLabel * Label1; private: // User declarations void __fastcall ProcessMessage (TMsg & message, bool & handled); public: // User declarations __fastcall TForm1 (TComponent * Owner);} ; ---- 3, unit1.cpp, the increase in the program statement ProcessMessage function: void __fastcall TForm1 :: ProcessMessage (TMsg & message, bool & handled) {if (message.message == WM_SYSCOMMAND && message.wParam == SC_SCREENSAVE) { Handled = true;}} ---- 4, in TFORM1 constructor adds the following code: __fastcall tform1 :: tForm1 (tComponent * Owner): TFORM (OWNER) {Application-> OnMessage = processMessage;} Display / hidden taskbar icon ---- Standard Windows application runtime generally display task icons on the taskbar, users can click the taskbar icon directly to switch, but some applications do not use the taskbar icon, such as the typical Office toolbar. Some programs can be displayed or hidden in the taskbar icon such as Winamp. You can also do in our program, as long as the Windows API function setWindowl is called, as follows: // Hidden Task Bar Icon: SetWindowlong (Application-> Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW); // Display Task Bar Icon: SetWindowlong (Application-> Handle, GWL_EXSTYLE, WS_EX_APPWINDOW); Mailbox monitor . In addition to the Winsock programming knowledge, it is necessary to understand the POP3 protocol. The lower surface is a rough introduction to POP3, and readers can see the RFC 1225 more detailedly to solve this agreement. First, the POP3 protocol ---- POP3 server program is often available in TCP port 110. When the customer wants to use the service, it will set up a TCP connection with the server. Once connected to the establishment, the POP3 service will send a welcome message to the customer. Then the passenger will send the commander to the server, and the server gives a negative answer. The command of POP3 is set by a keyword or keyword word. Each command is made as a end bunch of backhand (0xD0XA). For all the commands, the POP3 serviceter will provide an answer. The replies of the server are added to a status marker to add some additional information. The two markers used in front of the purpose are " OK" and "-err", and the demonstration of the table is the order of the customer. All replies are also in the end of the return. ---- The four POP3 commands that are related to the topics discussed in this article are User, Pass, List and Quit. User Mandarin Merrange User Name ---- Name in it is the user ID of the user on the POP3 service. The customer should send this command after the welcome message picks up the servers or after the last user or passenger is lost. Pass command format pass string ---- String in it is the password of the user. The rear of the customer will send this command after sending the user command and receives a OK answer. If the estate name and password are correct, the server replied OK, and no -ERR. List command format LIST ---- If the user has an email, the list command will answer OK, list all the identifiers and sizes of all mail (one row each), the last line contains only one period (0x0xa0x2e) indicates the end of the entire answer . If the user does not have a message, some servitators will return to -RR, and some can return to one OK and a row that only contains one of the stations. Of course, the customer must pass the client program to send a list command to the server after passing the pass command. Quit command ---- Reverse your login from the POP3 server. Second, real-see-related functions ---- Next, the communication rules called Pop3Checkmail in accordance with the communication regulations defined by the POP3 protocol, just call this function, we can detect the mailbox. ---- The code under the lower surface is in Pascal language with Delphi 4, we must include Winsock Units and initialize the Winsock dynamic connection library before calling the following functions. The code for initialization of Winsock motion connection is as follows: ---- IF WSASTARTUP ($ 002, Wsadata) <> 0 Then Halt; ---- Pop3checkmail's prototype: ---- Function Pop3checkmail (Email, Password: string; var maillist: tstringlist; var errormsg: string): BOOL; ----Parameter Description: ---- Email and Password Divide the user's Email mailbox name and password. ---- Variable parameter MAILLIST is used to return the identity of the message and the size of the Mailist.count indicates the number of mail. ---- Variable parameter erroormsg returns to the wrong message. ---- Under the implementation code of POP3CHECKMAIL and its functions used. Connect_server function ---- Function: Set up a TCP connection with the specified host, return to an Socket description. The parameter host specifies the name of the host, the port specifies the port number. Function Connect_server (Host: integer): Integer; var i: integer; p: ^ longint; Phe: phostent; sin: sockaddr_in; begin sin.sin_family: = afrin sin_family: = AF_INET; SIN.SIN_PORT: = HTONS (port); // get the ip for host, allowing for dotted decimal Phe: = gethostByname (pchar (host)); if Phe <> nil dam p: = POINTER (PHE ^ .h_addr_list ^); sin.sin_addr.s_addr: = P ^; ELSE BEGIN I: = inet_addr (pchar (host)); if i <> -1 Then sin.sin_addr.s_addr: = I end; // Create a socket result: = socket (pf_inet, sock_stream, 0); IF (Result = INVALID_SOCKET) THEN EXIT; // Connect To Server IF Connect (Result, SiN, SIZEOF (SIN)) = SOCKET_ERROR THEN BEGIN {Error Handling} end; Write_socket function ---- Fenergy: Write a string to Socket. Function Write_Socket (Sockfd: Integer; Const S: String): Integer; Begin Result: = Winsock.send (Sockfd, Pointer (S) ^, Length (s), 0) end; Socket_readline function ---- Function: Read the line from the Socket. Function socket_readline (sockfd: integer): string; // read uncle # 10 var s: string; buf: array [0..1] of char; N: cardinal; begin buf [0]: = # 0; buf [1 ]: = # 0; s: = '; N: = Recv (SOCKFD, BUF, 1, 0); while n> 0 do begin buf [1]: = # 0; s: = s buf; if (BUF [0] = # 10) Then Break; N: = RECV (SOCKFD, BUF, 1, 0); End; Result: = Trim (s); end; pop3Response function ---- Function: Read a line of POP3 server to return information, if it is " ok", the function returns to Ture, if it is "-err", returns false. Function pop3Response (sockfd: integer): Bool; var s: string; begin s: = socket_readline (sockfd); if Copy (s, 1, 3) = ' ok' Ten Result: = true else {if Copy (S, 1 , 4) = '-ERR' TEN} Result: = false; POP3CHECKMAIL function ---- Function: Specting the name of the email, if there is a new message, then return the size of each piece of mail to the variable parameter Mailist. Function Pop3checkmail (Email, Password: String; var maillist: tstringlist; var sarormsg: string): Bool; var sockfd, i: integer; s, host, user: string; begin result: = false; errormsg: = '; if Maillist = NIL THEN EXIT; S: = Trim (email); i: = POS ('@', email); user: = trim (COPY (S, 1, I -1)); Host: = Trim (COPY S, I 1, Length (email) -i); maillist.clear; if (user = ') or (host =') THEN BEGIN ERRORMSG: = 'Invalid Email Address.'; EXIT; End; IF Host [1] = '[') AND (Host [Length (Host)] = ']') THEN Begin Host [1]: = '; Host [Length (Host)]: = # 0; End; Host: = Trim (host); sockfd: = connect_server (Host, 110); if not pop3Response (sockfd) THEN BEGIN ERRORMSG: = 'Cannot Connect To Server'; EXIT; End; Write_Socket (Sockfd, 'User' User # 13 # 10); if not pop3Response (SOCKFD) THEN BEGIN ERRORMSG: = 'user failed'; exit; end; write_socket (sockfd, 'pass' password # 13 # 10); if not pop3Response (sockfd) THEN BEGIN ErrorMsg: =' Pass Failed '; EXIT; End; Write_Socket (Sockfd,' List '# 13 # 10); pop3Response (sockfd); while true do begin s: = socket_readline (sockfd); if S = '.' Ten Break; Mailist.Add (s); end; write_socket (sockfd, 'quit' # 13 # 10); CloseSocket (SOCKFD); Result: = true; Third, the emotion of the message ---- Let me look at a simple example of using a POP3CHECKMAIL function. var MailList: TstringList; ErrorMsg: String; ... MailList: = TstringList.Create; POP3CheckMail ('simon_liu@263.net ',' mypassword ', MailList, ErrorMsg); If MailList.Count> 0 then MessageBox (0, Pchar ('You Have' INTOSTR (Mailist.count) 'New Messages!' MessageBox (0, Pchar (ErrorMsg), 'Error', 0); Mailist.Free; ---- If you read the implementation code of the Pop3checkmail function, you will find that this function can get the number of emails, You can also get the size of each email. You can get the size of the mail with the Strings archive array of variable parameter maillist in the POP3CHECKMAIL function. ---- Implement the pop3checkmail function, and then write a status of a POP3 mailbox on this basis. You can call Pop3checkmail functions with a timer, which you can monitor an email mailbox. If you want to monitor multiple Email mailboxes, just create a thread for each mailbox and set the POP3CHECKMAIL function in the thread. In your program, there is no control to use Delphi, and a complete mailbox monitoring process can only be only 60K left. C building make a alarm clock ---- Dafan's nematon has been caught in the following dilemma: about 7:30 in the late place, but in front of the computer, it has been crawling to the middle of the night, and the friends have already dreedly. I have had a few days of Kung Fu to apologize. Why don't you do a simple alarm clock as follows, let you go online, big party. As long as you open this application when you go online, you can set the time (of course, you can also be a default). When the time arrives, the music sounds, goes to date. ---- This alarm program has the following components: No. Component Type Component Name Function 1 Tlabel l_Clock_1 "Enter Date" 2 TdateTimePicker dtp_Clock_1 choose a date 3 Tlabel l_Clock_2 "Enter Time" 4 TdateTimePacker tdp_Clock_2 selection time 5 TmediaPlayer mp_Clock playing music 6 Tbutton b_Clock_Open reopen 7 Ttimer t_Clock timing detector 8 Tbutton b_Clock_Close Close application ---- Table of Screen Components ---- Screen component list ---- Description: DTP_CLOCK_1 The Kind property set to DTKDATE, DTP_CLOCK_2 set to DTKTIME, the FileName property of MP_CLOCK is set to any MID, WAV, AVI file existing on your host. The T_Clock's INTERVAL property is set to 10. ---- The incident is as follows: ①, t_Clock the OnTimer: {// time to trigger demo struct date d; struct time t; AnsiString thour, tmin, tsec; int dyear; int dintyear; int dmon, dday; AnsiString tinthour, tintmin, tintsec; AnsiString dintmon, dintday ; // Take the day getDate (& D); DYEAR = D.DA_Year; DDAY = D.DA_DAY; DMON = D.DA_MON; DINTYEAR = STRTOINT (DINT.SUBSTRING (1, 2)); DINTMON = DINT.SUBSTRING (4 , 2); DINTDAY = DINT.SUBSTRING (7, 2); // Take the time GetTime (& T); THOUR = ANSISTRING; TMIN = Ansistring (t.ti_min); // Tsec = Ansistring (T .ti_sec); // Tint = Ansistring (DateTimePicker1-> Time); TINTHOUR = Tint.substring (10, 2); Tintmin = Tint.substring (13, 2); //tintsec=tint.substring (16, 2) ; // Alarm Service Function IF ((StrtOINT (THOUR) == STRTOINT (TINTHUR) & STRTOINT (TMIN) == StrtOINT (TINTMIN) & (STRTOINT (ANSISTRING (Dyear) .substring (3, 2)) = = DINTYEAR) && (STRTOINT (DMON) == STRTOINT (DINTMON)) && (dtimon)) && (DDAY) == STRTOINT (DINTDAY)))) {dtimer-> enabled = false; MediaPlayer1-> open (); MediaPlayer1-> Play ( );}} 2, b_clock_open's onclick: {t_clock-> enabled = true;} 3, b_clock_close's onclick {application-> t Erminate (); ---- Of course, this procedure can also expand, refine, as I only detect the trigger condition, of course, it can detect seconds, or only detect. Instructions for dialing the IP address With the rapid spread of the Internet, there is more and more people in the Internet. Among them, most people are dial online by ordinary telephone lines. We know that every Internet computer, no matter what way to internet, allocated one or more independent IP addresses. For users dial-up Internet access, it is generally allocated by its ISP to dynamically allocate an IP address every time it is dial, this address may not be the same each time (whose reason is mainly to make full use of limited resources). So, can we manage the IP address when you internetrate through some way? The answer is yes. Below we use C Builder to develop a small program to implement this function. (Note: This program can also run in the local area network) ---- First use the New Application under the BCB's File menu to create a new project, named IPCheck.bpr. ---- Then add five tags (Label) and two buttons (button) on the form FORM1, as shown. ---- Next, double-click the oncreate event of the form, plus the following procedures: Void __fastcall tform1 :: formcreate (TOBJECT * Sender) {Wsadata Wsadata; IF (WSAStartup (MakeWord (1, 1), & WSADATA! = 0) {// Initializing Winsock call MessageBox (Null, "Wrong Winsock Version", "Error", MB_OK; Return;} Refresh1click (sender); // The program is adjusted to the IP address} Double-click the Refresh button, plus the following procedure Void __fastcall tform1 :: refresh1click (TOBJECT * Sender) // Refresh IP address {char hostname [80]; LPHOSTENT LPHOSTENT; Struct in_addr addr [2]; // This program assumes that the host is not a multi-hockey host, that is, most // A network card and a dynamic IP for (int i = 0; i <2; i ) {MEMSET (& addr)); // Turn 0 for the IN_ADDR structure, filled in the back } IF (getHostname) == Socket_ERROR) {// Get this host name MessageBox (Null, "Can't getting local host name.", "Error", MB_OK; Return;} Label3-> CAPTION = hostname; LPHOSTENT = gethostByname (Hostname); // Using the get the host name to get the host structure IF (! lphostent) { MessageBox (NULL, "YOW! BAD HOST LOOKUP.", "Error", MB_OK; Return; } For (int i = 0; lphostent-> h_addr_list [i]! = 0; i ) // Get the IP address from the host address table { Memcpy (& addr [i], lphostent-> h_addr_list [i], sizeof (IN_ADDR)); } Label4-> CAPTION = INET_NTOA (AddR [0]); Label5-> CAPTION = inet_ntoa (addr [1]); Double-click the Refresh button, plus the following procedure Void __fastcall tform1 :: button2click (Tobject * Sender) { Wsacleanup (); // Release Winsock call CLOSE (); } ---- Finally, don't forget to add #include ---- Well, the program is completed, and it can be run after compiling. This program compiles through Chinese WIN95 / NT4.0. Write the TRAY program with C Builder TRAY is a special area on the Windows 9x task bar. Its technical name is "taskbar jet", some software (such as Jinshan Word III) runs an icon on the tray when running, using the user to know This program is running in the background. It is easy to activate it. It usually only needs to click this icon, it is very convenient. TRAY programming is special, but it is not difficult, mainly including three aspects such as icons, tool tips, and messages, which are part of the shell programming. Shellapi provides a shell-notifyicon function that can be used, delete, or modify the icon in the tray. After placing the icon on the tray, the Windows Shell will be responsible for notifying the app on the icon. The shell-notifyicon function is defined as follows: Winshellapi Bool WinApi Shell-Notify, PNOTICONDATA PNID; DwMessage denotes actions to be completed: NIM-Add (Add Icon), NIM-delete (delete icon), NIM-Modify (modify icon or prompt text), PNID is a pointer to the Notifyicondata structure, the definition of the structure is as follows: Typedef struct -notifyicondata { DWORD CBSIZE; / / The number of bytes of the structure must be initialized with the size of the structure. HWND hWnd; // Accept the window handle of the TRAY icon message UINT UID; // The icon ID defined by the application UINT UFLAGS; // Used to identify domains that need to change their values, Nif_icon indicates that HICON is valid, can be used to modify the icon, Nif_Message is used to be valid, used to define messages, NIF-TIP indicates that the SZTIP parameter is valid, modify the tooltip. UINT UCALLBACKMESSAGE; / / application definition message Hicon Hicon; // TRAY icon handle Char Sztip [64]; // Text of Tool Tips NOTIFYICONDATA; Below we will explain the implementation method through a concrete example, the program is running without displaying a main form, and only an icon is added to the tray, double-click the icon to close the program. The program runtime tray area is displayed as follows: Create a new project to place a Timer control to the form. Open the unit1.h file, add the header file description #include Unsigned int iconMessage; // definition message Void addtrayicon (); // Add icon on the tray Void removetrayicon (); // Remove icon from the tray Since the processing to the custom message is to be added, the Window Process Function WndProc must be overused, and the protected section is added in the definition of TFORM1: Virtual Void - FastCall WndProc (Messages :: TMESSAGE & Message); defined in Unit1.cpp Member function: Void TFORM1 :: AddTrayicon () { Notifyicondata iconData; MEMSET (& iconData, 0, Sizeof (icondata); // initialize the domain of structure iconData to 0 Icondata.cbsize = sizeof (icondata); Icondata.hwnd = handle; STRNCPY (icondata.sztip, "unknown status", sizeof (icondata.sztip); IconData.hicon = Application-> icon-> handle; IconData.ucallbackMessage = iconMessage; IconData.uflags = nif-message | NIF-ICON | NIF-TIP; Shell-Notifyicon (Nim-Add, & IconData); } Void TFORM1 :: Removetrayicon () { Notifyicondata iconData; MEMSET (& iconData, 0, Sizeof (icondata); Icondata.cbsize = sizeof (icondata); Icondata.hwnd = handle; Shell-Notifyicon (Nim-delete, & iconData); } Repetition TFORM1's WndProc function, add processing code for custom messages, which is actually equivalent to the subclass of the TFORM class. Void __fastcall tform1 :: wndproc (Messages :: tMessage & Message) { IF (message.msg == iconMessage) { IF (message.lparam == WM-LBUTTONDBLCLK) { Application-> Terminate (); // If you double-click the icon, turn off the application. } Return; } TFORM :: WndProc (Message); // For additional messages, call the base class's WndProc function to make Windows default. } Create a form of oncreate event handle: Void - FastCall TFORM1 :: Formcreate (TOBJECT * SENDER) { IconMessage = registerWindowMessage ("iconnotify"); Addtrayicon (); } A user message is defined by calling the RegisterWindowMessage function, or a message number that is not used by WM_USER N can also be obtained. Void - FastCall TFORM1 :: FormDestroy (TOBJECT * SENDER) { REMOVETRAYICON (); // The form deletes the icon in the tray when it is closed. } Write the Timer event code of Timer1, when the user leaves the mouse on the icon, display the prompt text: Void - FastCall TFORM1 :: Timer1Timer (TOBJECT * Sender) { Notifyicondata iconData; Memset (& iconData, 0, Sizeof (icondata); icondata.cbsize = sizeof (icondata); Icondata.hwnd = handle; String s = "My icon!"; // Define the prompt text STRNCPY (icondata.sztip, s.c_str (), sizeof (icondata.sztip); Icondata.uflags = niF-tip; Shell-Notifyicon (Nim-Modify, & iconData); } The program is running when the program is running, and only the corresponding program icon is placed on the tray, select View | Project Source from the C Builder Gatherings, add the code after the application → initialize () statement of the Winmain function: ShowWindow (Application → Handle, SW-HIDE); Application → ShowMainform = False; Press F9 to compile and run the program, the corresponding icon will appear on the tray. The above code is compiled in C Builder3, PWIN98 environments and runs. How to minimize or recover from code You can implement it with one of the following three methods. Method 1: Send a Windows message to the Handle property or Application-> Handle of the main window. This message is WM_SYSCOMMAND, set WPARAM to SC_MINIMIZE or SC_RESTORE. You can call the SendMessage API function to send messages. / / Set wPARAM to minimize windows for SC_MINIMIZE SendMessage (Application-> Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0); / / Set wPARAM to recover the window for SC_RESTROE SendMessage (Application-> Handle, WM_SYSCOMMAND, SC_RESTORE, 0); Method 2: Call the ShowWindow API function. You must send the Application object handle to the showWindow function. If you are transmitted to the slogwindow function is a main window, the main window will minimize Desktop instead of a task bar. / / Minimize: Transfer SW_MINIMIZE to ShowWindow ShowWindow (Application-> Handle, SW_MINIMIZE); // Restore: Transfer SW_RESTORE to ShowWindow ShowWindow (Application-> Handle, SW_RESTORE); Method 3: Call the Minimize or RESTORE function of the Application object. // Call Minimize Minimize Application Application-> minimize (); // Call the Restore Recovery Application Application-> restore (); The method of calling Application is more useful, but the WM_SYSCOMMAND message is sent is stronger. In addition, the WM_SYSCOMMAND message allows you to maximize the program, change the cursor to help the cursor, scrolling program, move a window, change the window size, and even simulate the ALT-Tab to another window. Keep in keeping, achieving these functions is better with an API function. Despite the call showWindow work, you probably don't want to use it to minimize or recover procedures. ShowWindow causes the minimization animation when the hidden window is minimized. This looks a little stupid because the animation is far from the center of the program main window. Copyright window before making the main window display In the project file, I selected File-> New Form to create a window to design the look of the window. The window is called AboutBox, the source file is named AboutBox.cpp Choose Project-> Options, remove the new window from automatic creation. Select View-> Project Source, open the source file of the project file, add the sentence. #include "aboutbox.h" WinApi Winmain (Hinstance, Hinstance, LPSTR, INT) { DWORD LTIME; Try { Application-> Initialize (); AboutBox = New TaboutBox (Aboutbox); Aboutbox-> show (); Aboutbox-> Update (); LTIME = gettickcount (); Application-> CreateForm (__ classid (tMAINFORM), & mainform); WHILE ((GettickCount () - LTIME) / 1000 <3); Aboutbox-> hide (); Aboutbox-> free (); Application-> Run (); } Catch (Exception & Exception) { Application-> Showexception (& Exception); } Return 0; } Judging whether there is already an Internet Use the NetMasters PowerSock control to read the local IP address if it is "0.0.0.0" instructions. Example: void __fastcall tform1 :: button1click (TOBJECT * Sender) {if (PowerSock1-> localip == "0.0.0.0") ShowMessage ("Not Connected"); Else ShowMessage (PowerSock1-> localip);} Get login username Void __fastcall tform1 :: button2click (TOBJECT * Sender) {dword dwsize = 0; // Determine the byte required memory getUserName (null, & dwsize); // Defines buffer char * szbuf = new char [dwsize]; szbuf [0 ] = '/ 0'; // Read User Name GetUsername (SZBUF, & DWSize); Label2-> CAPTION = SZBUF; delete [] szbuf;} Hide desktop icon Void __fastcall tform1 :: button1click (TOBJECT * Sender) {hwnd hdesktop; // Get the desktop handle hDesktop = findwindow ("progman", null); // hide icon showwindow on the desktop ShowWindow;} // ----------------- -------------------------------------------------- ------------ Void __fastcall tform1 :: button2click (TOBJECT * Sender) {hwnd hdesktop; hdesktop = findwindow ("progman", null); // Display icon showWindow on the desktop;} Run when the program starts Void __fastcall tform1 :: button1click (TOBJECT * Sender) {Tregistry * reg; char Appfilename [256]; If (edit1-> text == ") // determines if the file name is empty {MessageBox (Handle," application name is not empty. "," Error ", MB_OK MB_ICONERROR); EXIT (0);} Edit1 -> GetTextBuf (AppFileName, 256); REG = New Tregistry (); try {reg-> rootkey = hkey_local_machine; if (REGT> OpenKey ("Software // Microsoft // Windows // CurrentVersion // Run", FALSE) ) {// Add value REG-> WritestRing ("Startup1", AppFileName);} else messageBox (Handle, "Open the registry failed.", "Error", MB_OK | MB_ICONERROR);} catch (.. .) {REG-> CloseKey (); reg-> free ();}} Control panel call Void __fastcall tform1 :: button1click (TOBJECT * Sender) {uint res; // Winexe return result // Display Control Panel RES = WINEXEC ("Rundll_Rundll", 9); if (res == 0) MessageBox (Handle, "program beyond memory.", "Error", MB_OK | MB_ICONERROR); Else if (res == error_bad_format) messageBox (Handle, "Command Error.", "Error", MB_OK | MB_ICONERROR); Else If (res == Error_File_not_found) messageBox (Handle, "specified file is not found.", "Error" , MB_OK | MB_ICONEROR); Else if (res == error_path_not_found) messageBox (Handle, "specified path is not found.", "Error", MB_ok | MB_ICONERROR);} // ------------ -------------------------------------------------- ------------- Void __fastcall tform1 :: butt2click (TOBJECT * Sender) {// Auxiliary Options | Keyboard Winexec ("Rundll_Rundll Access.cpl, 1", 9);} // ------- -------------------------------------------------- ------------------ Void __fastcall tform1 :: button3click (Tobject * sender) {// Add / Remove Program Properties | Installation / Uninstall Winexec ("Rundll32.exe shell32.dll , Control_Rundll AppWiz.cpl, 1 ", 9);} // ---------------------------------------------------------------- ----------------------------------------- void __fastcall tform1 :: button4click (TOBJECT * Sender) {// Display Properties | Background Winexec ("Rundll32.exe Shell32.dll, Control_Rundll Desk.cpl, 0", 9);} // ---------------- -------------------------------------------------- --------- void __fastcall tform1 :: button5click (TOBJECT * Sender) {// Internet property | General Winexec ("Rundll32.exe shell32.dll, control_rundll inetcpl.cpl, 0", 9);} / / -------------------------------------------------------------------------------------------- --------------------------- void __fastcall tform1 :: butt6click (TOBJECT * Sender) {// Area Setting Properties | Area Setting WINEXEC (" Rundll32.exe shell32.dll, contro L_Rundll INTL.CPL, 0 ", 9);} // ----------------------------------- ---------------------------------------- void __fastcall tform1 :: button7click (Tobject * Sender ) {// Game controller | General Winexec ("Rundll32.exe shell32.dll, control_rundll joy.cpl, 0", 9);} // ---------------- -------------------------------------------------- --------- void __fastcall tform1 :: button8click (TOBJECT * Sender) {// Mouse Properties | Button Winexec ("Rundll_Rundll Main.cpl", 9);} // -------------------------------------------------- ------------------------ Void __fastcall tform1 :: button9click (Tobject * sender) {// Multimedia Property | Audio WINEXEC ("Rundll32.exe shell32. DLL, Control_Rundll MMSYS.CPL, 0 ", 9); } // ----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------- Void __fastcall tform1 :: button10click (TOBJECT * Sender) {// Modem Properties Winexec ("Rundll32.exe Shell32.dll, Control_Rundll Modem.cpl, 9);} // ------------------------------------------------------------------------------------------------------------------------------------------------------------ ----------------------------------------- void __fastcall tform1 :: button11click (TOBJECT * Sender) {// Network | Configuring Winexec ("Rundll_Rundll Netcpl.cpl", 9);} // ---------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- ----- void __fastcall tform1 :: button12click (TOBJECT * Sender) {// Password Properties | Change Password Winexec ("Rundll_Rundll Password.cpl", 9);} // ---- -------------------------------------------------- --------------------- void __fastcall tform1 :: button13click (TOBJECT * Sender) {// Scanner and Digital Camera Properties | Equipment Winexec ("Rundll32.exe shell32 .dll, control_rundll sticpl.cpl, 9);} // ----------------------------------- ---------------------------------------- void __fastcall tform1 :: button14click (TOBJECT * Sende r) {// System Properties | General Winexec ("Rundll32.exe Shell32.dll, Control_Rundll Sysdm.cpl, 0", 9);} // ---------------- -------------------------------------------------- --------- void __fastcall tform1 :: button15click (TOBJECT * Sender) {// Date / Time Properties | Date and Time Winexec ("Rundll32.exe Shell32.dll, Control_Rundll Timedate.cpl", 9); } // ----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------- void __fastcall tform1 :: button16click (TOBJECT * Sender) {// Power Management Properties | Power Scenario Winexec "Rundll32.exe shell32.dll, control_rundll powerpfg.cpl", 9); } // ----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------- Void __fastcall tform1 :: button17click (TOBJECT * Sender) {// Dial Properties | My location Winexec "Rundll32.exe shell32.dll, control_rundll telephon.cpl", 9);} analog keyboard button Void __fastcall tform1 :: button1click (TOBJECT * Sender) {// Simulation Press the letter A in the Edit1 component PostMessage (Edit1-> Handle, WM_KeyDown, 65, 0);} // -------- ------------------------------------------- Void __fastcall tform1 :: time1tim (TOBJECT * Sender) {// Simulation Press Tab 1 in Form1 POSTMESSAGE (Form1-> Handle, WM_KeyDown, VK_TAB, 0);} // -------- ---------------------------------- Let the title bar flash Void __fastcall tform1 :: button1click (TOBJECT * Sender) {// Activation Timer Timer1-> enabled = true;} // --------------------- -------------------------------------------------- - Void __fastcall tform1 :: button2click (TOBJECT * Sender) {// Disable timer Timer1-> enabled = false; // Restore the form to the original flashwindow (Handle, False);} // --------- -------------------------------------------------- ---------------- Void __fastcall tform1 :: time1timer (TOBJECT * Sender) {// Make the form header bar flash flashwindow (Handle, True); beep (); // Sound prompt} Start screen protection SendMessage (hwnd_broadcast, wm_syscommand, sc_screensave, 0); Year and month, weeks Ansistring Iyear, IMONTH, IDAY, IHOUR, IMINUTE, ISECOND; IYEAR = now (). FormatString ("YYYY"); // Near IMONTH = now (). Formatstring ("mm"); // 取 月 iDay = now (). Formatstring ("DD"); // Take IHOUR = now (). FormatString ("hh"); // Take the hour iMinute = now (). FormatString ("nn"); // Take the minute ISecond = Now (). Formatstring ("ss"); // Take a second dayofweek (now (). CurrentDate ()) Keyboard event Void __fastcall tform1 :: formkeydown (tobject * sender, word & key, tshiftstate shift) // If the Shift button is pressed, Shift Statusbar1-> Panels-> Items [0] -> text = "shift"; if (SHIFT.CONTAINS (SSALT)) // If the ALT button is pressed, the ALT STATUSBAR1-> Panels-> Items [1] -> "is displayed on the second panel. Text = "alt"; if (SHIFT.CONTAINS (SSCTRL)) // If the CTRL button is pressed, the ctrl statusbar1-> panel-> items [2] -> text = "ctrl" is displayed on the third panel. IF (Shift.Contains (SSALT) && (Shift.contains (SSCTRL))) // If you press the Alt Ctrl key at the same time, display Alt Ctrl Statusbar1-> Panels-> Items [5] on the second panel -> Text = "alt ctrl";} // ------------------------------------- -------------------------------------- Void __fastcall tform1 :: formkeyup (Tobject * Sender, WORD & Key, tshiftstate shift {// In Shift, Alt and Ctrl key bomb the contents of the content IF on the corresponding panel in the status bar (! (Shift.contains (ssshift))) statusbar1-> panels-> items [0] - > Text = ""; if (! (Shift.contains (ssalt))) statusbar1-> panels-> items [1] -> text = ""; if (! (Shift.contains (ssctrl))) statusbar1-> PANELS-> Items [2] -> text = ""; if (! Shift.contains (ssalt) && (! Shift.contains (ssctrl) )) STATUSBAR1-> Panels-> items [5] -> text = "";} // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------- Void __fastcall tform1 :: formousedown (TOBJECT * SENDER, TMOUSEBUTTON Button, TshiftState Shift, INT X, INT Y) // If the left button is pressed, LEFT is displayed on the fourth panel. Statusbar1-> panels-> items [3] -> text = "left"; if (Shift.contains (SSMIDDLE)) // If the midkey is pressed, display middle statusbar1-> panels-> in the fifth panel Items [4] -> text = "middle"; if (SSDOUBLE)) // If you are double-clicked, display Double Statusbar1-> Panels-> Items [5] -> Text = "on the sixth panel. Double ";} // ------------------------------------------------------------------------------------------------------------------------------------ ------------------------------- void __fastcall tform1 :: formouseup (Tobject * Sender, TMousebutton Button, TshiftState Shift, Int X , int y) {// When the mouse button bombs the content IF on the corresponding panel in the status bar (! (Shift.contains (ssleft))) statusbar1-> panels-> items [3] -> text = "" ; if (! (! (!)))))) "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" 5] -> Text = ""; Hidden taskbar Void __fastcall tform1 :: button1click (TOBJECT * Sender) {hwnd wndhandle; // Get the window handle of the taskbar WNDHANDLE = FindWindow; showwindow (wndhandle, sw_show); // Display taskbar} // ------------------------------------------------------------------ -------------------------------------------------- --------- Void __fastcall tform1 :: button2click (TOBJECT * Sender) {hwnd wndhandle; WndHandle = FindWindow ("shell_traywnd", null; showwindow (wndhandle, sw_hide); // Hidden taskbar} // ------------------------ -------------------------------------------------- - Void __fastcall tform1 :: formcreate (TOBJECT * Sender) {setWindowlong (Application-> Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW); Shutdown 1. First open the header file as follows: class TForm1: public TForm {__published: // IDE-managed Components private: // User declarations void __fastcall WMQueryEndSession (TWMQueryEndSession & msg); public: // User declarations __fastcall TForm1 (TComponent * Owner); BEGIN_MESSAGE_MAP MESSAGE_HANDLER (WM_QUERYENDSESSION, TWMQueryEndSession, WMQueryEndSession ) END_MESSAGE_MAP (TFORM)}}}}}}; // ------------------------------------------------------------------------------------------------------------------------- ---------------------------------- EXTERN PACKAGE TFORM1 * FORM1; / / -------- -------------------------------------------------- ----------------- # Endif2. Then add the following code to the unit.cpp file: Void __fastcall tform1 :: wmqueryendSession (TWMQueryEndSession & msg) {msg.result = 0; showMessage ("You cannot close the system"); How to start the program in a minimized manner You can call the Application-> Minimize function to minimize the application to the task bar. How do you want your program to minimize when you start, just call Application-> minimize before calling the RUN method. WinAPI WinMain (Hinstance, Hinstance, LPSTR, INT) {Application-> Initialize (); Application-> Createform (__ classid (tform1), & form1); Application-> minimize (); // Start Application- > Run ();} catch (exception-> showexception;} return 0;} How to make the last line can always display after the Memo increases SendMessage (Memo1-> Handle, EM_Scroll, SB_LINEDOWN, 0) Set wallpaper method Implemented through the IactiveDesktop interface For example, set wallpaper, you can IactiveDesktop * a; Coinitialize (NULL); IF (CocreateInstance) SHLOBJ :: CLSID_ACTIVEDESKTOP, NULL, CLSCTX_INPROC_SERVER, IID_IACTIVEDESKTOP, (void **) & a)))))) { WideString C = "c: // my docuuments // yw2.jpg"; Olecheck (A-> Setwallpaper (C.c_BSTR (), 0)); OLECHECK (A-> ApplyChanges (ad_apply_all); A-> Release (); } Couninitialize (); Other interfaces can be viewed by MSDN Note to the first row of CPP #define no_win32_lean_and_mean And want #include