/* * Experiments with language/layout stuff for win32. * 04.01.2016 (dd.mm.yyyy) * Allen Webster */ // TOP // NOTE(allen): This is a bare bones window opening and message pumping // application. I created it to search for a way to get the language bar // to behave correctly when my window has focus. As of the 4th of January, // I have not yet found the solution. // // Log of Insanity // DAY 2: // Thanks to "insofaras" from the handmade_hero chat for finding the solution // to this problem. Turns out the messages for the language bar were being blocked // by my process because my reading of some MSDN documentation was too hasty. Go // to GetMessage to see a full description of the problem I was having. // // // DAY 1: // I looked around MSDN for a while, reading about lots of layout manipulating // functions. I also found the WM_INPUTLANGECHANGE message, but that message is // apparently passed AFTER the language is changed, and the problem is that I can't // change the languge using the GUI, so it doesn't seem like the right direction. // // I also looked around the emacs source and tried matching some of the settings // used there including WS_CLIPCHILDREN, and I tried using SetCapture/ReleaseCapture // similarly to emacs code but none of that fixed the problem either. #include struct Win32Vars{ int keep_playing; } win32; LRESULT WinCallback( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){ LRESULT result = 0; switch(uMsg){ case WM_QUIT: case WM_DESTROY: { win32.keep_playing = 0; }break; // NOTE(allen): This was here to investigate the effects of capturing and especially // releasing mouse input, I have blocked them out for now because they didn't help // and I might want other messages of the same type in the future. #if 0 case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: { SetCapture(hwnd); }break; case WM_LBUTTONUP: case WM_RBUTTONUP: { ReleaseCapture(); }break; #endif default: { result = DefWindowProcW(hwnd, uMsg, wParam, lParam); }break; } return(result); } int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){ WNDCLASS winclass = {}; winclass.style = CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WinCallback; winclass.hInstance = hInstance; winclass.lpszClassName = "lang-test-class"; ATOM winclassatom = RegisterClassA(&winclass); if (winclassatom == 0){ return(1); } HWND window = CreateWindowA( "lang-test-class", "lang test window", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, 0, 0, hInstance, 0); if (window == 0){ return(2); } ShowWindow(window, SW_SHOW); // NOTE(allen): This is here to investigate what happens when the layout // is changed in code. On Windows 7 I observed the language bar updating what // it displayed, but only if I dragged the window over the bar, or did something else // to force it to redraw. If you only have one layout loaded, nothing will happen here. HKL locales[2]; int locale_count = GetKeyboardLayoutList(2, locales); if (locale_count > 1){ ActivateKeyboardLayout(locales[1], 0); } for (win32.keep_playing = 1; win32.keep_playing;){ MSG msg; // NOTE(allen): This turns out to be the crucial point. The second parameter filters out // messages by a window handle, and it turns out the language bar is one of those things // that needs to process input through the active process but the messages aren't tied // to your main window, so those messages get blocked if you put the handle there. Long // story short: put a 0 there. GetMessage(&msg, 0, 0, 0); TranslateMessage(&msg); DispatchMessage(&msg); } return(0); } // BOTTOM