[Restricting program only opens an example]

zhaozj2021-02-16  55

[Restriction program open only one instance] [Author: Fictiony (fictiony@china.com)] [reprint please indicate the source when we do some of the program management platform classes (such as Windows Task Manager), they often need to limit The program can only open an instance. The rough idea of ​​solving this problem is simple, nothing more than judging if there is a process of being in the same way, if there is, turn it off, otherwise it will run. However, the problem is how to discriminate whether there is a process with yourself. I searched the relevant article online, I found that the solution is not more than the following ways: 1. Use :: CREATEMUTEX to create a mutually exclusive object when the process is initialized, and determine if the mutex is existing Whether the program has been run. This method is indeed very easy to implement whether the discriminator instance already exists, only needs to add the following statement at the beginning of the InitInstance method: m_hunique = :: Createmutex (null, false, unique_id);

IF (getLastError () == error_already_exists) return false; unique_id is a string with uniqueness, usually use VC to automatically generate the identification macro (already .h file on top of the top of the top of the .h file. ), Of course, you can also generate it yourself by tools, and you will be better. It should be noted that don't forget to turn the mutectable object in the exitInstance method. But this approach has a big problem, it is difficult to get the main window handle that has opened the program instance. And most of us, you need to activate the main window of that program instance. To get the main window handle, you need to use other methods mentioned later. 2. Traverse all the open process main windows, compare the window title, if you find the title of the condition, indicating that the program has run and activate the window. Although the program's main window can be found, the problem is obvious: a. What should I do if the window title changes (such as the file name of the document in the title)? B. What should I do if the main window title of other programs is just the same as the program? The first question can be solved by writing a registry or writing the INI file. That is, when the main window title changes, the new title is written to the registry or INI file. However, this kind of solution is also troublesome. -_- || The second question is troubles, at least I have not found a good solution. If you have to say one, then I suggest that you "try to do a way", "unscrupulous means" is absolutely different. However, it is estimated that this step is done, you are almost gone. 3, use: SetProp to the main window to add an attribute value that has a uniqueness of the attribute to be judged by traverse all windows at the time of the process. The code to add attribute values ​​can be placed at the end of the InitInstance method, as follows:: setProp (m_pmainwnd-> m_hwnd, "unique_id", (handle) unique_id); unique_id is an integer value with uniqueness (why not use strings • Because the comparison of the string needs to read the string, this can only record the string address, and this address is meaningless in other programs, so this string cannot be read). This way only problem is how to determine that the integer value is unique. The solution we have raised later is based on this method. After summarizing the pros and cons of the above ways, I found that only a unique value with uniqueness is required for the program, on the one hand, whether or not the program has been running (:: createmutex actually similar concept On the other hand, it can be assigned to the main window by using this value to find the main window handle of the open program instance. Thus, the Atom is sent to the field (the ATOM variable type is equivalent to Word, and thus is an integer value). The amount of Atom is inherent is the key identifier of the hash table, and its correspondence is a string. Each program has its own Atom scale, while Windows also has a global ATOM table. The method we need to use is to create a global ATOM quantity, and if you exist it to determine if the program has been run, and you can identify this main window by adding this amount as an attribute value to the main window. The specific process is as follows: 1. Add a ATOM type member variable to the main program App class: m_aappid, as the program ID.

2, add the following code at the beginning of the InitInstance method (unique_id is a string macro with uniqueness): m_aappid = :: globalfindatom (UNIQUE_ID); // Find the program ID whether there is an IF (M_AAPID) // program ID existence, activation has been opened Program instance of the main window

{

HWND HWND = :: getWindow (:: getForegroundWindow (), gw_hwndfirst);

For (; hwnd; hwnd = :: getwindow (hwnd, gw_hwndnext))

{

IF ((atom) :: getprop (hwnd, "app_id") == m_aappid)

{

If (: isiconic (hwnd)) :: ShowWindow (hwnd, sw_restore; // To restore the minimized window

:: setForegroundWindow (hwnd); // Activation window

m_aappid = 0; // Assignment 0 is to prevent the amount of Atom found in ExitInstance from being removed

Break;

}

}

Return False;

}

Else // The program ID does not exist, create a program ID

{

m_aappid = :: GlobalAddatom (app_id);

} 3, add identification attributes to the main window in the initInstance method: :: setProp (M_PMainWnd-> M_HWND, "App_ID", (Handle) M_AAPPID); 4. Add the following code to delete the program ID: if (m_aappid) in the exitInstance method :: GLOBALDETEATOM (M_aAppid); Experience: The amount of Atom used in this method is an application wide technology, such as :: CreateMutex, :: setProp, etc. API function is indirectly used atom. Using it, we can do a lot of things that need to be used for uniqueness.

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

New Post(0)