Global handle for focus window ?
void OnNotify(HWND hwnd, int idCtrl, NMHDR* pNMHdr)
{
if (pNMHdr->code == NM_SETFOCUS)
g_hWndFocus = pNMHdr->hwndFrom;
}
void OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized)
{
static HWND hWndF;
switch(state) {
case WA_INACTIVE:
hWndF = GetFocus();
break;
case WA_ACTIVE:
case WA_CLICKACTIVE :
if (hWndF) {
SetFocus(hWndF);
} else SetFocus(g_hWndFocus);
break;
}
}
EDIT: Example for testing.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#define IDC_LISTVIEW 4002
#define IDC_TREEVIEW 4003
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct);
static void OnDestroy(HWND hwnd);
static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
//static void OnSize(HWND hwnd, UINT state, int cx, int cy);
static void OnNotify(HWND hwnd, int idCtrl, NMHDR* pNMHdr);
static void OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized);
static HWND MakeListView(HWND hWnd, UINT wId);
static HWND MakeTreeView(HWND hWnd, UINT wId);
char *szAppName = "WinFrame";
char *szFrameClass = "cWinFrame";
HWND hFrame;
HANDLE hInst;
HWND g_hWndTV, g_hWndLV;
HWND g_hWndFocus;
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcx;
MSG msg;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = (WNDPROC) WndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground= (HBRUSH)COLOR_APPWORKSPACE+1;
wcx.lpszMenuName = NULL;
wcx.lpszClassName= szFrameClass;
wcx.hIconSm = 0;
if (!RegisterClassEx(&wcx))
return 0;
hInst = hInstance;
hFrame = CreateWindowEx(0, szFrameClass, szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL);
if(!hFrame) return 0;
ShowWindow(hFrame, nCmdShow);
UpdateWindow(hFrame);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch (wMsg)
{
case WM_COMMAND:
return OnCommand(hWnd, (int)(LOWORD(wParam)), (HWND) (lParam), (UINT)HIWORD(wParam)), 0;
// case WM_SIZE:
// return OnSize(hWnd, (UINT) (wParam), (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam)), 0;
case WM_NOTIFY:
return (OnNotify(hWnd, (int)(wParam), (NMHDR *) (lParam)), 0);
case WM_ACTIVATE:
return (OnActivate(hWnd,(UINT)LOWORD(wParam),(HWND)lParam,(BOOL)HIWORD(wParam)),0);
case WM_CREATE:
return OnCreate(hWnd, (LPCREATESTRUCT) (lParam)), 0;
case WM_DESTROY:
return OnDestroy(hWnd), 0;
default:
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
}
static BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)
{
InitCommonControls();
g_hWndTV = MakeTreeView(hWnd, IDC_TREEVIEW);
g_hWndLV = MakeListView(hWnd, IDC_LISTVIEW);
MoveWindow(g_hWndTV, 1, 1, 200, 100, TRUE);
MoveWindow(g_hWndLV, 205, 1, 200, 100, TRUE);
TVINSERTSTRUCT tvins;
memset(&tvins, 0, sizeof(tvins));
tvins.item.mask = TVIF_TEXT;
tvins.item.pszText = "Root";
TreeView_InsertItem(g_hWndTV, &tvins);
SetFocus(g_hWndTV);
g_hWndFocus = g_hWndTV;
LVCOLUMN lvc;
lvc.mask = LVCF_TEXT | LVCF_WIDTH;
lvc.cx = 50;
for (int i=0; i<2; i++) {
lvc.iSubItem = i;
lvc.pszText = "C";
ListView_InsertColumn(g_hWndLV, i, &lvc);
}
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.pszText = "row1";
lvi.iItem = 0;
lvi.iSubItem = 0;
ListView_InsertItem(g_hWndLV, &lvi);
return 0;
}
static void OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
}
static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id) {
/*
case IDM_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0L);
return;
*/
}
}
static void OnNotify(HWND hwnd, int idCtrl, NMHDR* pNMHdr)
{
char szTmp[100];
if (pNMHdr->code == NM_SETFOCUS) {
wsprintf(szTmp, "%Xh TV:%Xh LV:%Xh", pNMHdr->hwndFrom, g_hWndTV, g_hWndLV);
OutputDebugString(szTmp);
g_hWndFocus = pNMHdr->hwndFrom;
}
}
static void OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized)
{
static HWND hWndF;
switch(state) {
case WA_INACTIVE:
hWndF = GetFocus();
break;
case WA_ACTIVE:
case WA_CLICKACTIVE :
if (hWndF) {
SetFocus(hWndF);
} else SetFocus(g_hWndFocus);
break;
}
}
static HWND MakeListView(HWND hWnd, UINT wId)
{
HWND hWndLV;
hWndLV = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL,
WS_CHILD | WS_VISIBLE | WS_TABSTOP | LVS_REPORT
,0, 0, 0, 0,
hWnd, (HMENU)wId, hInst, NULL);
if (hWndLV) {
SendMessage(g_hWndLV,LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_GRIDLINES, LVS_EX_GRIDLINES);
SendMessage(hWndLV, LVM_SETBKCOLOR, 0, CLR_NONE);
}
return hWndLV;
}
static HWND MakeTreeView(HWND hWnd, UINT wId)
{
HWND hWndTV = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, NULL,
WS_CHILD | WS_VISIBLE | WS_TABSTOP |
TVS_HASLINES | TVS_LINESATROOT |
TVS_HASBUTTONS
,0, 0, 0, 0,
hWnd, (HMENU)wId, hInst, NULL);
return hWndTV;
}
EDIT: edit controls.static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
if (codeNotify == EN_SETFOCUS) {
g_hWndFocus = hwndCtl;
}
}