PreSCRIPT: Apologies to post the question again, the last post has two different code snippet and makes the message bigger so reposting.
Thanks for your help in advance, i desperately need it.
--------------------------------------------------------------------
Hi There,
I am using the following example to make Win32 tab control without using MFC.
There are some business reasons that I can only use Win32 API for this.
I am able to create the tab pages. But finding weird behaviour with the messageloop.
I am making an XLL, so my dialog is opened from a selection from Excel menu item.I get a dialog box with tabs on clicking this certain menu item. Each tab has some edit boxes and buttons. which all work fine except the TAB key doesnt work to move from one item to another.
I have implemented it the same way as in above program. The problem i face are:
1. When i click on the tabs, it shows me the correct child dialog. when i change the selection of tab, it goes to the correct next dialog. so everything works fine here. But when i click on any area in the child dialog (i.e to activate the message loop), The tab key starts working on that particular selected tab, BUT after this i am not able to select any other tab. On clickin on any other tab takes me to the first tab (iSel=0)
2. When I close the dialog box from the X button in top right corner; It closes the dialog box BUT it also closes my Excel window which i dont want.
This application I am developing to configure and test some connections. so I need the excel window open after i am done with the configurations.
Please reply if you read this message. I will appreciate any help.
I have debugged it ...
it all goes fine as long as you dont click on the tab(LBUTTONDOWN) or VK_DOWN ( to focus on the page) to start the message loop.
Once you start it, Id doesnt stop i guess.
during the debug:
1. When I only clicked on the tabs and NOT on the tab dialogs( meaning not called TabPageMessageLoop() function) I can change the tabs, use the buttons int he tabs ( without the tab key working for the traversal on the controls)
2. Once i click on the tab page, or i click the down key( which start the messahe loop so that the Tab key can work in the controls), Now the tab key starts working, but only on the currentl page and when u select another tab, it displays Tab number 0( the first tab) always. so in a way the tab selection doesnt work any more.
attached is the whole code required to analyse.
Please help me finding out where the loop resets the m_lptc pointer that it always points to tab-0.
Regards
typedef struct TabControl
{
HWND hTab;
HWND hVisiblePage;
HWND* hTabPages;
LPSTR *tabNames;
LPSTR *dlgNames;
int tabPageCount;
BOOL blStretchTabs;
BOOL (CALLBACK *ParentProc)(HWND, UINT, WPARAM, LPARAM);
void (*TabPage_OnSize)(HWND hwnd, UINT state, int cx, int cy);
BOOL (*Notify) (LPNMHDR);
BOOL (*StretchTabPage) (HWND, INT);
BOOL (*CenterTabPage) (HWND, INT);
}TABCTRL, *LPTABCTRL;
static TABCTRL TabCtrl_1;
static LPTABCTRL m_lptc;
#define CMD_VK_ESCAPE 101
#define CMD_VK_RETURN 102
HINSTANCE g_hinst;
HWND hWndSummit;
static SIZE gMinSize;
static HWND frmMain;
static BOOL stopTabPageMessageLoop=FALSE;
void CAuthenticationAddin::Configure()
{
try
{
g_hinst = m_hInstance;
InitCommonControls();
DialogBox(m_hInstance, MAKEINTRESOURCE(IDD_AUTH_TAB),NULL, (DLGPROC)AuthDialogProc);
}
catch (CBaseException &e)
{
LoggedMessageBox(e, "Configure");
}
catch (...)
{
LoggedMessageBox("Unexpected exception", "Configure");
}
Log("CAuthenticationAddin::Configure() - after DisplayDialog()");
}
VOID CAuthenticationAddin::TabCtrl_OnKeyDown(LPARAM lParam)
{
TC_KEYDOWN *tk=(TC_KEYDOWN *)lParam;
int itemCount=TabCtrl_GetItemCount(tk->hdr.hwndFrom);
int currentSel=TabCtrl_GetCurSel(tk->hdr.hwndFrom);
if(itemCount <= 1) return;
switch (tk->wVKey)
{
case VK_NEXT:
{
if(0==currentSel) return;
TabCtrl_SetCurSel(tk->hdr.hwndFrom, currentSel-1);
TabCtrl_SetCurFocus(tk->hdr.hwndFrom, currentSel-1);
}
break;
case VK_LEFT:
{
if(0==currentSel) return;
TabCtrl_SetCurSel(tk->hdr.hwndFrom, currentSel-1);
TabCtrl_SetCurFocus(tk->hdr.hwndFrom, currentSel);
}
break;
case VK_PRIOR:
{
TabCtrl_SetCurSel(tk->hdr.hwndFrom, currentSel+1);
TabCtrl_SetCurFocus(tk->hdr.hwndFrom,currentSel+1);
}
break;
case VK_RIGHT:
{
TabCtrl_SetCurSel(tk->hdr.hwndFrom, currentSel+1);
TabCtrl_SetCurFocus(tk->hdr.hwndFrom,currentSel);
}
break;
case VK_UP:
{
SetFocus(m_lptc->hTabPages[currentSel]);
CAuthenticationAddin::TabPageMessageLoop (m_lptc->hTabPages[currentSel]);
}
break;
case VK_DOWN:
{
SetFocus(m_lptc->hTabPages[currentSel]);
CAuthenticationAddin::TabPageMessageLoop (m_lptc->hTabPages[currentSel]);
}
break;
default: return;
}
}
VOID CAuthenticationAddin::TabControl_GetClientRect(HWND hwnd,RECT* prc)
{
RECT rtab_0;
LONG lStyle = GetWindowLong(hwnd,GWL_STYLE);
GetWindowRect(hwnd, prc);
ScreenToClient(GetParent(hwnd), (POINT*)&prc->left);
ScreenToClient(hwnd, (POINT*)&prc->right);
TabCtrl_GetItemRect(hwnd,0,&rtab_0);
prc->top = prc->top + (6 + rtab_0.bottom-rtab_0.top);
prc->left = prc->left + 4;
prc->bottom = prc->bottom - (16 + rtab_0.bottom-rtab_0.top);
prc->right = prc->right - 12;
}
BOOL CAuthenticationAddin::TabCtrl_OnSelChanged(VOID)
{
stopTabPageMessageLoop = TRUE;
int curSel = TabCtrl_GetCurSel(m_lptc->hTab);
ShowWindow(m_lptc->hVisiblePage,FALSE);
ShowWindow(m_lptc->hTabPages[curSel],TRUE);
m_lptc->hVisiblePage = m_lptc->hTabPages[curSel];
return TRUE;
}
BOOL CAuthenticationAddin::Notify (LPNMHDR pnm)
{
m_lptc = (LPTABCTRL) GetWindowLong(pnm->hwndFrom,GWL_USERDATA);
switch (pnm->code)
{
case TCN_KEYDOWN:
TabCtrl_OnKeyDown((LPARAM)pnm);
case TCN_SELCHANGE:
return TabCtrl_OnSelChanged();
}
return FALSE;
}
VOID CAuthenticationAddin::TabControl_Destroy(LPTABCTRL tc)
{
for (int i=0;i<tc->tabPageCount;i++)
DestroyWindow(tc->hTabPages[i]);
free (tc->hTabPages);
}
BOOL CAuthenticationAddin::StretchTabPage (HWND hTab, INT iPage)
{
RECT rect;
m_lptc = (LPTABCTRL) GetWindowLong(hTab,GWL_USERDATA);
TabControl_GetClientRect(hTab, &rect);
return SetWindowPos(m_lptc->hTabPages[iPage], HWND_TOP,
rect.left, rect.top, rect.right, rect.bottom,
0);
return FALSE;
}
BOOL CAuthenticationAddin::CenterTabPage (HWND hTab, INT iPage)
{
RECT rect, rclient;
m_lptc = (LPTABCTRL) GetWindowLong(hTab,GWL_USERDATA);
TabControl_GetClientRect(hTab, &rect);
GetClientRect(m_lptc->hTabPages[iPage], &rclient);
rclient.right=rclient.right-rclient.left;
rclient.bottom=rclient.bottom-rclient.top;
rclient.left= rect.left;
rclient.top= rect.top;
if(rclient.right<rect.right)
rclient.left += (rect.right-rclient.right)/2;
if(rclient.bottom<rect.bottom)
rclient.top += (rect.bottom-rclient.bottom)/2;
return SetWindowPos(m_lptc->hTabPages[iPage], HWND_TOP,
rclient.left, rclient.top, rclient.right, rclient.bottom,
0);
return FALSE;
}
VOID CAuthenticationAddin::TabPage_OnSize(HWND hwnd, UINT state, INT cx, INT cy)
{
}
VOID CAuthenticationAddin::New_TabControl(LPTABCTRL lptc,
HWND hTab,
LPSTR *tabNames,
LPSTR *dlgNames,
BOOL (CALLBACK* ParentProc)(HWND, UINT, WPARAM, LPARAM),
VOID (*OnSize)(HWND, UINT, int, int),
BOOL fStretch)
{
static TCITEM tie;
m_lptc=lptc;
SetWindowLong(hTab,GWL_USERDATA,(long)m_lptc);
m_lptc->hTab=hTab;
m_lptc->tabNames=tabNames;
m_lptc->dlgNames=dlgNames;
m_lptc->blStretchTabs=fStretch;
m_lptc->ParentProc=ParentProc;
m_lptc->Notify=&Notify;
m_lptc->StretchTabPage=&StretchTabPage;
m_lptc->CenterTabPage=&CenterTabPage;
m_lptc->tabPageCount = 0;
LPSTR* ptr=m_lptc->dlgNames;
while(*ptr++) m_lptc->tabPageCount++;
m_lptc->hTabPages = (HWND*)malloc(m_lptc->tabPageCount * sizeof(HWND*));
tie.mask = TCIF_TEXT | TCIF_IMAGE;
tie.iImage = -1;
for (int i = 0; i< m_lptc->tabPageCount; i++)
{
tie.pszText = m_lptc->tabNames[i];
TabCtrl_InsertItem(m_lptc->hTab, i, &tie);
if (i==0)
m_lptc->hTabPages[i] = CreateDialog(g_hinst,
m_lptc->dlgNames[i],
GetParent(m_lptc->hTab),
(DLGPROC)ConfigureSummitDialogProc);
if (i==1)
m_lptc->hTabPages[i] = CreateDialog(g_hinst,
m_lptc->dlgNames[i],
GetParent(m_lptc->hTab),
(DLGPROC ) ConfigureRiskDialogProc);
if (i==2)
m_lptc->hTabPages[i] = CreateDialog(g_hinst,
m_lptc->dlgNames[i],
GetParent(m_lptc->hTab),
(DLGPROC) ConfigureUtilDialogProc);
if (i==3)
m_lptc->hTabPages[i] = CreateDialog(g_hinst,
m_lptc->dlgNames[i],
GetParent(m_lptc->hTab),
(DLGPROC) ConfigureExtDataDialogProc);
if(m_lptc->blStretchTabs)
m_lptc->StretchTabPage(m_lptc->hTab, i);
else
m_lptc->CenterTabPage(m_lptc->hTab, i);
}
ShowWindow(m_lptc->hTabPages[0],SW_SHOW);
m_lptc->hVisiblePage = m_lptc->hTabPages[0];
}
HACCEL CAuthenticationAddin::CreateAccTable (VOID)
{
static ACCEL aAccel[1];
static HACCEL hAccel;
aAccel[0].fVirt=FVIRTKEY;
aAccel[0].key=VK_ESCAPE;
aAccel[0].cmd=CMD_VK_ESCAPE;
aAccel[1].fVirt=FVIRTKEY;
aAccel[1].key=VK_RETURN;
aAccel[1].cmd=CMD_VK_RETURN;
hAccel=CreateAcceleratorTable(aAccel,1);
return hAccel;
}
void CAuthenticationAddin::TabPageMessageLoop (HWND hwnd)
{
MSG msg;
int status;
BOOL handled = FALSE;
HACCEL hAccTable = CAuthenticationAddin::CreateAccTable();
while((status = GetMessage(&msg, NULL, 0, 0 )) != 0 && !stopTabPageMessageLoop)
{
if (status == -1)
{
return;
}
else
{
handled = TranslateAccelerator(hwnd,hAccTable,&msg);
if(!handled)
handled=IsDialogMessage(hwnd,&msg);
if(!handled)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
if(stopTabPageMessageLoop)
{
DestroyAcceleratorTable(hAccTable);
stopTabPageMessageLoop = FALSE;
return;
}
DestroyAcceleratorTable(hAccTable);
PostQuitMessage(0);
return;
}
VOID CAuthenticationAddin::ResetTabPageMessageLoop (HWND hwnd)
{
stopTabPageMessageLoop=TRUE;
stopTabPageMessageLoop=FALSE;
SetFocus(hwnd);
CAuthenticationAddin::TabPageMessageLoop(hwnd);
}
BOOL CAuthenticationAddin::FormMain_OnNotify(HWND hwnd, INT id, LPNMHDR pnm)
{
switch(id)
{
case TAB_CONTROL_1:
return TabCtrl_1.Notify(pnm);
}
return FALSE;
}
void CAuthenticationAddin::FormMain_OnSize(HWND hwnd, UINT state, int cx, int cy)
{
RECT rc;
GetClientRect(hwnd,&rc);
MoveWindow(TabCtrl_1.hTab,0,0,(rc.right - rc.left)/2-4,rc.bottom - rc.top,FALSE);
for(int i=0;i<TabCtrl_1.tabPageCount;i++)
TabCtrl_1.StretchTabPage(TabCtrl_1.hTab,i);
}
void CAuthenticationAddin::FormMain_OnClose(HWND hwnd)
{
PostQuitMessage(0);
TabControl_Destroy(&TabCtrl_1);
EndDialog(hwnd, 0);
}
void CAuthenticationAddin::InitHandles (HWND hwndParent)
{
BOOL initialized=FALSE;
if(!initialized)
{
if (frmMain != hwndParent) frmMain = hwndParent;
initialized=TRUE;
}
}
BOOL CAuthenticationAddin::FormMain_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
InitHandles (hwnd);
static LPSTR tabnames[]= {"Summit", "Risk", "Utility", "External Data", 0};
static LPSTR dlgnames[]= {MAKEINTRESOURCE(IDD_SB_DLG),
MAKEINTRESOURCE(IDD_RDB_DLG),
MAKEINTRESOURCE(IDD_UTILITY_DLG),
MAKEINTRESOURCE(IDD_EXTDATA_DLG),0};
New_TabControl( &TabCtrl_1,
GetDlgItem(hwnd, TAB_CONTROL_1),
tabnames,
dlgnames,
&AuthDialogProc,
NULL,
TRUE);
RECT rc;
GetWindowRect(hwnd,&rc);
gMinSize.cx = (rc.right - rc.left);
gMinSize.cy = (rc.bottom - rc.top);
return 0;
}
void CAuthenticationAddin::FormMain_OnCommand(HWND hWndDlg, int id, HWND hwndCtl, UINT codeNotify)
{
static bool warnOnSaveState = true;
static DisplayEnum rateDisplay = REAL_VAL;
static DisplayEnum spreadDisplay = REAL_VAL;
static bool keyFileState = false;
switch(id)
{
case IDOKSB:
case IDCANCELSB :
EndDialog(hWndDlg, IDCANCELSB);
EndDialog(GetParent(hWndDlg),IDCANCELSB);
break;
case IDOKRDB:
break;
case IDCANCELRDB :
break;
case IDC_TEST_BUTTON_RDB :
{
}
break;
case IDC_CHECK_KEYFILE :
{
}
break;
case IDC_RATE1 :
case IDC_RATE2 :
case IDC_RATE3 :
rateDisplay = RateDisplayFromButtonID(codeNotify);
CAuthenticationAddin::GetObject().SetRateDisplay(rateDisplay);
break;
case IDC_SPREAD1 :
case IDC_SPREAD2 :
case IDC_SPREAD3 :
case IDOKUTIL:
break;
case IDCANCELUTIL :
case IDC_TEST_BUTTON_UTIL :
{
}
break;
case IDOKED:
break;
case IDC_TEST_BUTTON_ED :
{
}
break;
case IDCANCELED :
case IDCANCEL :
}
}
BOOL CALLBACK CAuthenticationAddin::AuthDialogProc(
HWND hWndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
try
{
switch(message)
{
HANDLE_MSG (hWndDlg, WM_COMMAND, FormMain_OnCommand);
HANDLE_MSG (hWndDlg, WM_INITDIALOG, FormMain_OnInitDialog);
HANDLE_MSG (hWndDlg, WM_SIZE, FormMain_OnSize);
HANDLE_MSG (hWndDlg, WM_NOTIFY, FormMain_OnNotify);
default:
return FALSE;
}
}
catch (CBaseException &e)
{
CAuthenticationAddin::GetObject().LoggedMessageBox(e, "AuthDialogProc");
}
catch(...)
{
CAuthenticationAddin::GetObject().LoggedMessageBox("Unexpected exception", "AuthDialogProc");
}
return TRUE;
}
VOID CAuthenticationAddin::TabPage_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, INT x, INT y, UINT keyFlags)
{
CAuthenticationAddin::ResetTabPageMessageLoop (hwnd);
}
VOID CAuthenticationAddin::SummitTabPage_OnCommand(HWND hwnd, INT id, HWND hwndCtl, UINT codeNotify)
{
if(CMD_VK_ESCAPE==id)
{
stopTabPageMessageLoop=TRUE;
SetFocus(m_lptc->hTab);
return;
}
else if(CMD_VK_RETURN==id)
{
}
if(codeNotify == EN_KILLFOCUS && id == IDC_CONFIG_SERVER_SB)
{
SetServerName(GetDlgItemString(hwnd, IDC_CONFIG_SERVER_SB));
}
.
.
.
ForwardWMCommand(hwnd,id,hwndCtl,codeNotify);
}
VOID CAuthenticationAddin::RiskTabPage_OnCommand(HWND hwnd, INT id, HWND hwndCtl, UINT codeNotify)
{
if(CMD_VK_ESCAPE==id)
{
stopTabPageMessageLoop=TRUE;
SetFocus(m_lptc->hTab);
return;
}
else if(CMD_VK_RETURN==id)
{
}
.
.
.
ForwardWMCommand(hwnd,id,hwndCtl,codeNotify);
}
VOID CAuthenticationAddin::UtilTabPage_OnCommand(HWND hwnd, INT id, HWND hwndCtl, UINT codeNotify)
{
if(CMD_VK_ESCAPE==id)
{
stopTabPageMessageLoop=TRUE;
SetFocus(m_lptc->hTab);
return;
}
else if(CMD_VK_RETURN==id)
{
}
.
.
.
ForwardWMCommand(hwnd,id,hwndCtl,codeNotify);
}
VOID CAuthenticationAddin::ExtTabPage_OnCommand(HWND hwnd, INT id, HWND hwndCtl, UINT codeNotify)
{
if(CMD_VK_ESCAPE==id)
{
stopTabPageMessageLoop=TRUE;
SetFocus(m_lptc->hTab);
return;
}
else if(CMD_VK_RETURN==id)
{
}
.
.
ForwardWMCommand(hwnd,id,hwndCtl,codeNotify);
}
VOID CAuthenticationAddin::ForwardWMCommand(HWND hwnd, INT id,HWND hwndCtl,UINT codeNotify)
{
FORWARD_WM_COMMAND (hwnd,id,hwndCtl,codeNotify,m_lptc->ParentProc);
if(codeNotify!=0) return;
ResetTabPageMessageLoop (hwnd);
SendMessage(hwnd , WM_NEXTDLGCTL, (WPARAM)0, FALSE);
SendMessage(hwnd , WM_NEXTDLGCTL, (WPARAM)1, FALSE);
}
BOOL CALLBACK CAuthenticationAddin::ConfigureSummitDialogProc(
HWND hWndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
hWndSummit = hWndDlg;
try
{
static bool warnOnSaveState = true;
switch(message)
{
HANDLE_MSG (hWndDlg, WM_COMMAND, SummitTabPage_OnCommand);
HANDLE_MSG (hWndDlg, WM_LBUTTONDOWN, TabPage_OnLButtonDown);
case WM_INITDIALOG:
{
SetDlgItemString(hWndDlg, IDC_SB_USER, username);
SetDlgItemString(hWndDlg, IDC_SB_PASS, password);
.
.
return DefWindowProc(hWndDlg, message, wParam, lParam);
}
break;
case WM_HELP :
CAuthenticationAddin::GetObject().DoHelp(s_ConfigureDialogHelpContext);
break;
default:
return FALSE;
}
}
return TRUE;
}
BOOL CALLBACK CAuthenticationAddin::ConfigureRiskDialogProc(
HWND hWndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
std::string d ="";
long rr=0;
try
{
static bool warnOnSaveState = true;
switch(message)
{
HANDLE_MSG (hWndDlg, WM_COMMAND, RiskTabPage_OnCommand);
HANDLE_MSG (hWndDlg, WM_LBUTTONDOWN, TabPage_OnLButtonDown);
case WM_INITDIALOG:
{
.
.
.
return DefWindowProc(hWndDlg, message, wParam, lParam);
}
break;
case WM_HELP :
CAuthenticationAddin::GetObject().DoHelp(s_ConfigureDialogHelpContext);
break;
default:
return FALSE;
}
}
return TRUE;
}
BOOL CALLBACK CAuthenticationAddin::ConfigureUtilDialogProc(
HWND hWndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
try
{
static bool warnOnSaveState = true;
static DisplayEnum rateDisplay = REAL_VAL;
static DisplayEnum spreadDisplay = REAL_VAL;
static bool keyFileState = false;
switch(message)
{
HANDLE_MSG (hWndDlg, WM_COMMAND, UtilTabPage_OnCommand);
HANDLE_MSG (hWndDlg, WM_LBUTTONDOWN, TabPage_OnLButtonDown);
case WM_INITDIALOG:
{
.
.
.
return DefWindowProc(hWndDlg, message, wParam, lParam);
}
break;
case WM_HELP :
CAuthenticationAddin::GetObject().DoHelp(s_ConfigureDialogHelpContext);
break;
default:
return FALSE;
}
}
return TRUE;
}
BOOL CALLBACK CAuthenticationAddin::ConfigureExtDataDialogProc(
HWND hWndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
try
{
static bool warnOnSaveState = true;
switch(message)
{
HANDLE_MSG (hWndDlg, WM_COMMAND, ExtTabPage_OnCommand);
HANDLE_MSG (hWndDlg, WM_LBUTTONDOWN, TabPage_OnLButtonDown);
case WM_INITDIALOG:
{
.
.
.
return DefWindowProc(hWndDlg, message, wParam, lParam);
}
break;
case WM_HELP :
CAuthenticationAddin::GetObject().DoHelp(s_ConfigureDialogHelpContext);
break;
default:
return FALSE;
}
}
return TRUE;
}
|