2009-09-30 2 views
2

참고 : 코드 샘플은 단순화되었지만 전체 구조는 그대로 유지됩니다.시스템 트레이 아이콘으로 표시된 속성 시트가 ​​작업 표시 줄을 잠글 수있는 이유는 무엇입니까?

주 인터페이스가 시스템 트레이 아이콘 인 Win32 응용 프로그램에서 작업하고 있습니다. 이 메시지 전용 창을 참조, 그리고 아이콘이 생성됩니다

WNDCLASSEX wndClass; 
wndClass.lpfnWndProc = &iconWindowProc; 
// ... 
iconWindowHandle = CreateWindow(wndClass.lpszClassName, _T(""), 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, NULL, GetModuleHandle(NULL), 0); 

: 나는 아이콘의 메시지를 수신, 부모로 HWND_MESSAGE를 사용하여, 더미 윈도우를 생성

NOTIFYICONDATA iconData; 
iconData.hWnd = iconWindowHandle; 
iconData.uCallbackMessage = TRAYICON_MESSAGE; 
// ... 
Shell_NotifyIcon(NIM_ADD, &iconData) 

때 트레이 아이콘 두 번 클릭, 내가 만들고 (comctl32.dll에서) 속성 시트를 보여

LRESULT CALLBACK iconWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    switch (uMsg) { 
    case TRAYICON_MESSAGE: 
     switch (lParam) { // that contains the "real" message 
     case WM_LBUTTONDBLCLK: 
      showPropertySheet(); 
      return 0; 
     // ... 
     } 
     break; 
    // ... 
    } 
    return DefWindowProc(hWnd, uMsg, wParam, lParam); 
} 

속성 시트는 부모 윈도우가 없습니다. PropertySheet 함수는 메시지 전용 창의 윈도우 프로 시저에서 호출됩니다. PSH_MODELESS 플래그가 설정되어 있지 않습니다.

void showPropertySheet() { 
    PROPSHEETPAGE pages[NUM_PAGES]; 
    pages[0].pfnDlgProc = &firstPageDialogProc; 
    // ... 
    PROPSHEETHEADER header; 
    header.hwndParent = NULL; 
    header.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK; 
    header.ppsp = pages; 
    // ... 
    PropertySheet(&header); 
} 

이제 모든 일이 잘 작동, 내가 속성 시트의 페이지 중 하나의 대화 과정 내에서 중단 점을 설정할 때까지 :

BOOL CALLBACK firstPageDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
    return FALSE; // breakpoint here 
} 
속성 시트 창을 다시 닫은 후, 따라서, PropertySheet 만 반환

프로그램이 중단 점에서 중지되면 전체 작업 표시 줄이을 잠급니다!

호출 스택은 사용하지 않습니다. user32.dll 내부의 일부 호출을 통해 comctl32.dll 내부에서 다이얼로그 프로 시저가 호출되었음을 알 수 있습니다. 내 자신의 창 프로 시저가 중간에 없습니다.

속성 시트를 모덜리스로 만드는 것은 도움이되지 않습니다. 또한 코드를 더 복잡하게 만들기 때문에이 작업을 수행하지 않을 것입니다.

대화 상자 절차가 충분히 빠르게 반환되는 한, 이것은 문제가되지 않습니다. 하지만 대화 상자 프로 시저 내부의 긴 작업은 대화 자체를 잠글뿐만 아니라 전체 셸을 잠그는 것이 이상하게 보입니다. 메시지 전용 창 프로 시저가 트레이 아이콘과 더 밀접하게 관련되어 있기 때문에이 동작을 일으킬 수있는 힘이 있다고 상상할 수 있지만이 함수는 호출 스택에 표시되지 않습니다.

나는 근본적으로 잘못된 것을하고 있습니까? 누구든지이 문제에 관해 밝힐 수 있습니까?

답변

1

실제로, 그것은 명백한 것이고 혼란은 커피 부족 때문이었을 것입니다.

작업 표시 줄은 아마도 메시지를 처리 ​​할 때까지 차단하도록 응용 프로그램에 메시지를 보내려면 SendMessage을 사용합니다. SendMessageTimeout은 분명히 사용되지 않습니다.

여전히 내 자신의 기능이 호출 스택에 표시되지 않는다고 이상하다고 생각합니다. 물론, 이러한 메시지는 처리되기 위해 내 메시지 루프를 통과해야합니다. 아마도 "이 줄 아래에 프레임을 쌓아 놓는 것이 불완전하거나 누락 될 수 있습니다"라는 경고가 실제로 맞았습니다.