OSDN Git Service

Make minor modifications to the code to handle key configurations.
[xkeymacs/xkeymacs.git] / xkeymacs / AppList.cpp
1 #include "AppList.h"\r
2 #include "profile.h"\r
3 #include "imelist.h"\r
4 #include "../xkeymacsdll/AppName.h"\r
5 #include <vector>\r
6 \r
7 struct ProcArg {\r
8         CProperties* Properties;\r
9         std::vector<PROCESSENTRY32> Processes;\r
10 };\r
11 \r
12 void AppList::SetAppList(CProperties& cProperties)\r
13 {\r
14         ProcArg arg;\r
15         GetProcesses(arg.Processes);\r
16         arg.Properties = &cProperties;\r
17         EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&arg));\r
18 \r
19         TCHAR appTitle[MAX_APP][WINDOW_TEXT_LENGTH];\r
20         TCHAR appName[MAX_APP][CLASS_NAME_LENGTH];\r
21         CProfile::GetAppList(appTitle, appName);\r
22         for (int i = 0; i < MAX_APP; ++i) {\r
23                 if (!appName[i][0] || !_tcscmp(appName[i], _T("IME")))\r
24                         continue;\r
25                 if (CString(MAKEINTRESOURCE(IDS_DEFAULT)) == appName[i] ||\r
26                                 CString(MAKEINTRESOURCE(IDS_DIALOG)) == appName[i])\r
27                         continue;\r
28                 cProperties.AddItem(appTitle[i], appName[i]);\r
29         }\r
30         AddIMEInfo(cProperties);\r
31 }\r
32 \r
33 void AppList::GetProcesses(std::vector<PROCESSENTRY32>& list)\r
34 {\r
35         HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r
36         if (hProcessSnap == INVALID_HANDLE_VALUE)\r
37                 return;\r
38         PROCESSENTRY32 p;\r
39         p.dwSize = sizeof(PROCESSENTRY32);\r
40         if (Process32First(hProcessSnap, &p)) {\r
41                 do {\r
42                         list.push_back(p);\r
43                 } while (Process32Next(hProcessSnap, &p));\r
44         }\r
45         CloseHandle(hProcessSnap);\r
46 }\r
47 \r
48 BOOL CALLBACK AppList::EnumWindowsProc(HWND hWnd, LPARAM lParam)\r
49 {\r
50         ProcArg *arg = reinterpret_cast<ProcArg*>(lParam);\r
51         \r
52         TCHAR windowText[WINDOW_TEXT_LENGTH];\r
53         ::GetWindowText(hWnd, windowText, WINDOW_TEXT_LENGTH);\r
54         if (!(IsWindowVisible(hWnd) &&\r
55                         GetWindow(hWnd, GW_OWNER) == NULL &&\r
56                         windowText[0] != _T('\0')))\r
57                 return TRUE;\r
58 \r
59         CString appTitle;\r
60         DWORD procID;\r
61         GetWindowThreadProcessId(hWnd, &procID);\r
62         TCHAR appName[CLASS_NAME_LENGTH];\r
63         for (std::vector<PROCESSENTRY32>::const_iterator i = arg->Processes.begin(); i < arg->Processes.end(); ++i) {\r
64                 if (i->th32ProcessID != procID)\r
65                         continue;\r
66                 _tcscpy_s(appName, i->szExeFile);\r
67                 appTitle = GetAppTitle(windowText, appName);\r
68                 break;\r
69         }\r
70         arg->Properties->AddItem(appTitle, appName);\r
71         return TRUE;\r
72 }\r
73 \r
74 CString AppList::GetAppTitle(TCHAR (&windowText)[WINDOW_TEXT_LENGTH], TCHAR (&appName)[CLASS_NAME_LENGTH])\r
75 {\r
76         CString appTitle;\r
77         if (CString(MAKEINTRESOURCE(IDS_B2)).CompareNoCase(appName) == 0)\r
78                 appTitle.LoadString(IDS_BECKY);\r
79         else if (CString(MAKEINTRESOURCE(IDS_EXPLORER)).CompareNoCase(appName) == 0)\r
80                 appTitle.LoadString(IDS_PROGRAM_MANAGER);\r
81         else if (CString(MAKEINTRESOURCE(IDS_MSIMN)).CompareNoCase(appName) == 0)\r
82                 appTitle.LoadString(IDS_OUTLOOK_EXPRESS);\r
83         else if (CString(MAKEINTRESOURCE(IDS_PROJECT)).CompareNoCase(appName) == 0 ||\r
84                         CString(MAKEINTRESOURCE(IDS_EXCEL)).CompareNoCase(appName) == 0 ||\r
85                         _tcsicmp(_T("psp.exe"), appName) == 0 ||\r
86                         _tcsicmp(_T("devenv.exe"), appName) == 0)\r
87                 GetNthSegment(windowText, appTitle, 1);\r
88         else if (_tcsicmp(_T("sakura.exe"), appName) == 0)\r
89                 GetNthSegment(windowText, appTitle, 2); // '.' is included, so...\r
90         else if (CString(MAKEINTRESOURCE(IDS_MSDN)).CompareNoCase(appName) == 0)\r
91                 appTitle = windowText;\r
92         else if (_tcsicmp(_T("vb6.exe"), appName) == 0)\r
93                 appTitle = _T("Microsoft Visual Basic");\r
94         else if (_tcsicmp(_T("ssexp.exe"), appName) == 0)\r
95                 appTitle.LoadString(IDS_VISUAL_SOURCESAFE_EXPLORER);\r
96         else if (_tcsicmp(_T("mintty.exe"), appName) == 0)\r
97                 appTitle = _T("mintty");\r
98         else {\r
99                 AppName::CorrectAppName(windowText, appName);\r
100                 GetNthSegment(windowText, appTitle, -1);\r
101         }\r
102         return appTitle;\r
103 }\r
104 \r
105 // This function set the nth segment in a window name separated by " - "\r
106 // to the 2nd argument return whether it found an appropriate segment.\r
107 // If there aren't sufficient segments, it returns the last segment\r
108 // appropriate for the application title.\r
109 bool AppList::GetNthSegment(const CString& windowText, CString& part, int nth)\r
110 {\r
111         int sep = windowText.Find(_T(" - "));\r
112         if (sep < 0) {\r
113                 part = windowText;\r
114                 return false;\r
115         }\r
116         if (nth == 0) {\r
117                 part = windowText.Left(sep);\r
118                 return true;\r
119         }\r
120         if (GetNthSegment(windowText.Right(windowText.GetLength() - sep - 3), part, nth - 1) ||\r
121                         part.GetAt(0) != _T('[') && part.FindOneOf(_T(".]")) == -1)\r
122                 return true;\r
123         part = windowText.Left(sep);\r
124         return false;\r
125 }\r
126 \r
127 void AppList::AddIMEInfo(CProperties& cProperties)\r
128 {\r
129         IMEList imeList;\r
130         for (IMEListIterator p = imeList.begin(); p != imeList.end(); ++p)\r
131                 cProperties.AddItem(p->szDescription, p->szFileName);\r
132 }\r