Здраствуйте. По прежнему пишу свою программу, она уже давно работает, но есть ряд проблемм.
В роли клиентской части выступает программа, пользовательский интерфейс которой основан на Win32API MDI (без использования MFC). По некоторым причинам, там используется многопоточность и каждое дочернее окно MDI приложение работает в своем потоке. Проблемма в том, что в дочерних окнах не работает переключение раскладок, и для того, чтобы сменить раскладку на русскую, пользователю приходится перенести фокус на главное окно, переключить раскладку и вернуться к дочернему окну.. это не слишком удобно (хотя пользователи и не жалуются - они у меня верх мечтаний 

  )
Есть предположение, что данный баг вызван неправильной обработкой сообщений в многопоточном приложении. Вот как это примерно происходит (за вычетом несущественных деталей - если чтото покажется неясным, готов дать больше кода):
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  ....
  LC_KERNEL = new CClientKernel(); // Инациализация ядра программы
  ....
  LC_KERNEL->Start(); // Запуск ядра
  delete LC_KERNEL;
  ...
  return ret;
}
  DWORD dRes;
  
CClientKernel::Start() {
  ...
  m_hWnd = ::CreateWindowEx(0, GUI_MAIN_WINDOW_CLASS, "Client",
                        WS_TILEDWINDOW | WS_VISIBLE |  WS_CLIPCHILDREN | WS_MAXIMIZE,
                        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                        NULL, NULL, hInstance, (LPVOID)(some_info));
  // some_info - некая структура, используемая окном для, тут она не важна.
  // На самом деле, окно создается не непосредственно в этой функции, а через вызов мембера объекта класса CMainWin,
  // описанного в другом файле. Но создание объекта производится в тут.
  // (я субклассю окна, и в результате имею обект MainWin.)
  // Но если приводить здесь весь код то это будет слишком длинно
  ...
  // Запуск потоков ядра. В одном из этих потоков создаются сеансы
  ...
  MSG msg;
  while (GetMessage(&msg,hWnd,0,0)>0) {
    if ( msg.hwnd == NULL)
      continue;
    ::TranslateMessage( &msg );
    ::DispatchMessage( &msg );
  }
  ...
  return (LRESULT)msg.wParam;
}Внутри одного из потоков ядра, создается обект сеанса. Сеанс запускает отдельный поток и там создает свое дочернее окно через вызов метода главного окна приложения (приведен код этого метода):
int CMDIMainFrame::MDI_CreateClientWnd(CMenu * WindowMenu) {
  // Создание дочернего окна
  CLIENTCREATESTRUCT ccs;
  ccs.hWindowMenu = WindowMenu->GetHandle();
  ccs.idFirstChild = IDM_WINDOWCHILD;
  
  // Create the MDI client window.
  m_hWndClient = CreateWindowEx(0, "MDICLIENT", (LPCTSTR) NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
                              0, 0, 0, 0, m_hWnd, (HMENU) 0xCAC, App->GetInstance(), (LPSTR) &ccs);
  ::ShowWindow(m_hWndClient, SW_SHOW);
  return true;
}
После чего, в этом потоке сеанса запускается цикл обработки соообщений:
  MSG msg;
  while (GetMessage(&msg,hWnd,0,0)>0) {
    if ( msg.hwnd == NULL)
      continue;
    ::TranslateMessage( &msg );
    ::DispatchMessage( &msg );
  }
  return (LRESULT)msg.wParam;
Таким образом, главное окно (FRAME) и дочерние окна (MDI_CHILD) работают каждое в своем потоке и у всех есть свой цикл обработки сообщений.. Никакого упоминания о том, как производить обработку сообщений в многопоточных MDI приложениях, в MSDN я не нашел, однако меня смущает то, что во всех случаях циклы обработки ничем не отличаются.
По поводу переключения раскладок. Spy++ показал следующее (для поля вводе на дочернем окне при попытке сменить раскладку):
<00115> 076A05A4 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00116> 076A05A4 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00117> 076A05A4 P WM_INPUTLANGCHANGEREQUEST fSysCharset:True hkl:04190419
<00118> 076A05A4 S ..WM_IME_NOTIFY dwCommand:00000001 dwData:00000000
<00119> 076A05A4 R ..WM_IME_NOTIFY
<00120> 076A05A4 S ..WM_IME_NOTIFY dwCommand:00000002 dwData:00000000
<00121> 076A05A4 R ..WM_IME_NOTIFY
<00122> 076A05A4 S WM_INPUTLANGCHANGE charset:204 hkl:04190419
<00123> 076A05A4 S .WM_IME_NOTIFY dwCommand:0000000A dwData:00000000
<00124> 076A05A4 R .WM_IME_NOTIFY
<00125> 076A05A4 R WM_INPUTLANGCHANGE
<00126> 076A05A4 P WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<00127> 076A05A4 P WM_INPUTLANGCHANGEREQUEST fSysCharset:True hkl:04090409
<00128> 076A05A4 S ..WM_IME_NOTIFY dwCommand:00000001 dwData:00000000
<00129> 076A05A4 R ..WM_IME_NOTIFY
<00130> 076A05A4 S ..WM_IME_NOTIFY dwCommand:00000002 dwData:00000000
<00131> 076A05A4 R ..WM_IME_NOTIFY
<00132> 076A05A4 S WM_INPUTLANGCHANGE charset:0 hkl:04090409
<00133> 076A05A4 S .WM_IME_NOTIFY dwCommand:0000000A dwData:00000000
<00134> 076A05A4 R .WM_IME_NOTIFY
<00135> 076A05A4 R WM_INPUTLANGCHANGE
<00136> 076A05A4 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:1 fUp:1
А вот - что он же выдает при смене раскладки на главном окне (там есть листбокс):
<00178> 03820560 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00179> 03820560 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00180> 03820560 P WM_INPUTLANGCHANGEREQUEST fSysCharset:True hkl:04090409
<00181> 03820560 P WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<00182> 03820560 P WM_INPUTLANGCHANGEREQUEST fSysCharset:True hkl:04090409
<00183> 03820560 S ..WM_IME_NOTIFY dwCommand:00000001 dwData:00000000
<00184> 03820560 R ..WM_IME_NOTIFY
<00185> 03820560 S ..WM_IME_NOTIFY dwCommand:00000002 dwData:00000000
<00186> 03820560 R ..WM_IME_NOTIFY
<00187> 03820560 S WM_INPUTLANGCHANGE charset:0 hkl:04090409
<00188> 03820560 R WM_INPUTLANGCHANGE
<00189> 03820560 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:1 fUp:1
ПС. Кстати интересная деталь - данный баг наблюдается при запуске клиента в WinXP. Когда программа была запущена под Win2k такой проблеммы не было!  
 ППС. Проблемма существует уже давно, однако решить ее никак не удается. Я уже два раза открывал топик на эту тему, но это ничего не дало  

 . Буду признателен за любые мысли