하나의 창 인스턴스 만 실행하는 동안 문제가 발생합니다.C++ ShowWindow를 사용하여 창을 복원하면 최소화 기능이 비활성화됩니다.
구현 세부 정보 : 나는 작업 표시 줄에 아이콘으로 표시되는 C++ 응용 프로그램이 있습니다. 아이콘의 double-clik에서 ShellExecuteW 함수를 사용하여 새 델파이 창을 여는 중입니다. 이제는 사용자가 아이콘을 두 번 클릭 할 때마다 창 하나의 인스턴스 만 열어 여러 개의 창을 열지 않아도된다는 논리를 구현했습니다. 사용자가 아이콘을 두 번 클릭하고 이미 열린 창이있는 경우 창을 맨 앞에 가져 오거나 창이 최소화되면 창을 복원합니다.
이///////////////////////Double Click Code starts/////////////////////////
HWND hWnd = NULL;
HWND hWndFirst = NULL;
DWORD dw = FindProcessId("abc.exe");
if(dw == 0)
{
//Open new window
ShellExecuteW(0, L"open", acExePath, acParams, acFullPath, SW_SHOW);
hWndFirst = NULL;
}
else
{
//Open existing window
hWnd = hGetWindowHandleOfProcess(dw);
if(hWndFirst == NULL) hWndFirst = hWnd;
if(hWndFirst != hWnd)
{
//This is just a small work-around as minimizing the window was changing
//it's window handle. So I preserve the window handle the first time and
//use it whenever the window is minimized (i.e. the handle is changed)
SetForegroundWindow(hWndFirst);
ShowWindow(hWndFirst, SW_RESTORE);
}
else
{
SetForegroundWindow(hWnd);
ShowWindow(hWnd, SW_RESTORE);
}
}
///////////////////////Double Click Code ends///////////////////////////
///////////////////////Supporting functions/////////////////////////
struct ProcessHandleData
{
unsigned long lProcessId;
HWND hProcessWindowHandle;
};
//Finds the process id when given the process name
DWORD FindProcessId(char* pcProcessName)
{
char* pcBegin = strrchr(pcProcessName, '\\');
if(pcBegin)
pcProcessName = pcBegin+1;
PROCESSENTRY32 sProcessInfo;
sProcessInfo.dwSize = sizeof(sProcessInfo);
HANDLE sProcessesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (sProcessesSnapshot == INVALID_HANDLE_VALUE)
return 0;
Process32First(sProcessesSnapshot, &sProcessInfo);
if (!strcmp(pcProcessName, sProcessInfo.szExeFile))
{
CloseHandle(sProcessesSnapshot);
return sProcessInfo.th32ProcessID;
}
while (Process32Next(sProcessesSnapshot, &sProcessInfo))
{
if (!strcmp(pcProcessName, sProcessInfo.szExeFile))
{
CloseHandle(sProcessesSnapshot);
return sProcessInfo.th32ProcessID;
}
}
CloseHandle(sProcessesSnapshot);
return 0;
}
//Search predicate for EnumWindows function
BOOL CALLBACK bEnumWindowsSearcher(HWND handle, LPARAM lParam)
{
ProcessHandleData& sProcesshandleData = *(ProcessHandleData*)lParam;
unsigned long lProcessId = 0;
GetWindowThreadProcessId(handle, &lProcessId);
if (sProcesshandleData.lProcessId != lProcessId)
return true;
sProcesshandleData.hProcessWindowHandle = handle;
return false;
}
//Gets the window handle of the process (input process id)
HWND hGetWindowHandleOfProcess(unsigned long lProcessId)
{
ProcessHandleData sProcessHandleData;
sProcessHandleData.lProcessId = lProcessId;
sProcessHandleData.hProcessWindowHandle = 0;
EnumWindows(bEnumWindowsSearcher, (LPARAM)&sProcessHandleData); //enumerate all windows
return sProcessHandleData.hProcessWindowHandle;
}
문제 :가 위의 코드가 제대로 작동 코드 아래
는이 아이콘을 두 번 클릭하면 트리거, 나는 위의 로직을 구현하는 방법을 보여줍니다. 하지만 내가 직면하고있는 한 가지 문제가 있습니다. 열려있는 창이 활성 상태가 아니거나 창 뒤에있는 경우 위 코드는 예상 한대로 앞으로 가져옵니다. 그러나 창을 최소화하고 아이콘을 두 번 클릭하면 창을 복원하고 앞으로 다시 가져옵니다. 그러나이 작업을 수행 한 후에는 창 오른쪽 상단의 최소화 막대를 사용하여 창을 최소화 할 수 없습니다. 무언가가 (물리적으로가 아니라) 윈도우의 최소화 막대를 비활성화합니다.
Ay 도움말은이 점에 대해 크게 감사하겠습니다. 문제와 관련하여 추가 정보가 필요한 경우 알려 주시기 바랍니다.
감사합니다.
추신 : 위의 코드는 완전히 광산이 아닙니다. 다양한 웹 사이트를 조사하여 문제의 다양한 부분에 대한 코드를 얻었습니다.
감사 레미는, 그러나 RegisterWindowMessage abc.exe 델파이에서 음의 값을 반환합니다. 현재 왜 그런 일이 일어나고 있는지 조사 중입니다. – skmic
'RegisterWindowMessage()'는 '부호없는 정수'를 반환하므로 ** 음수 값을 반환 할 수 없습니다. 값을'UINT' 또는 적어도'LongWord'가 아닌 'Integer'에 할당해야합니다. –
그래, 알아 냈어. 이렇게 깨끗한 솔루션을 제공해 주셔서 다시 한 번 감사드립니다. – skmic