Fix debug assertion on link options dialog

Fix tab control offset problem
Enhance tab controls by graying out inoperable tabs 
Fix locked aspect ratio in Direct3D mode
This commit is contained in:
DJRobX 2007-11-02 09:19:38 +00:00
parent 5659db8a9a
commit 3b2b0e0431
4 changed files with 277 additions and 27 deletions

View File

@ -71,23 +71,23 @@ END
// Dialog
//
IDD_LINKTAB DIALOG 0, 0, 225, 162
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
IDD_LINKTAB DIALOGEX 0, 0, 254, 203
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Link Options"
FONT 8, "MS Sans Serif"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
CONTROL "Tab1",IDC_TAB1,"SysTabControl32",0x0,7,7,210,130
PUSHBUTTON "OK",ID_OK,31,140,60,15
PUSHBUTTON "Cancel",ID_CANCEL,114,140,57,15
CONTROL "Tab1",IDC_TAB1,"SysTabControl32",0x0,9,6,240,162
PUSHBUTTON "OK",ID_OK,57,180,60,15
PUSHBUTTON "Cancel",ID_CANCEL,140,180,57,15
END
IDD_LINKTAB1 DIALOG 0, 0, 210, 130
IDD_LINKTAB1 DIALOGEX 0, 0, 184, 79
STYLE DS_SETFONT | WS_CHILD | WS_VISIBLE
FONT 8, "MS Sans Serif"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
LTEXT "Link timeout (in milliseconds)",IDC_STATIC,17,12,92,16
EDITTEXT IDC_LINKTIMEOUT,116,10,53,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "Single Computer",IDC_LINK_SINGLE,"Button",BS_AUTORADIOBUTTON,17,27,71,16
CONTROL "Single Computer",IDC_LINK_SINGLE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,17,27,71,16
CONTROL "Network",IDC_LINK_LAN,"Button",BS_AUTORADIOBUTTON,17,43,70,16
END
@ -106,9 +106,9 @@ BEGIN
CONTROL "Speed hacks",IDC_SSPEED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,76,70,57,12
END
IDD_LINKTAB3 DIALOG 0, 0, 210, 108
IDD_LINKTAB3 DIALOGEX 0, 0, 188, 108
STYLE DS_SETFONT | WS_CHILD
FONT 8, "MS Sans Serif"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
CONTROL "TCP/IP",IDC_CLINKTCP,"Button",BS_AUTORADIOBUTTON | WS_GROUP,58,20,39,12
CONTROL "UDP",IDC_CLINKUDP,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,118,20,32,12
@ -1119,6 +1119,12 @@ END
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_LINKTAB, DIALOG
BEGIN
RIGHTMARGIN, 225
BOTTOMMARGIN, 162
END
IDD_OPENDLG, DIALOG
BEGIN
RIGHTMARGIN, 165

View File

@ -131,7 +131,7 @@ Direct3DDisplay::Direct3DDisplay()
width = 0;
height = 0;
filterDisabled = false;
keepAspectRatio = true; // theApp.d3dKeepAspectRatio;
keepAspectRatio = false; // theApp.d3dKeepAspectRatio;
lockableBuffer = false;
}

View File

@ -48,7 +48,6 @@ void LinkOptions::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(LinkOptions)
DDX_Control(pDX, IDC_TAB1, m_tabctrl);
//}}AFX_DATA_MAP
}
@ -59,13 +58,14 @@ BOOL LinkOptions::OnInitDialog(){
CDialog::OnInitDialog();
m_tabctrl.SubclassDlgItem(IDC_TAB1, this);
tabitem.mask = TCIF_TEXT;
for(i=0;i<3;i++){
tabitem.pszText = tabtext[i];
m_tabctrl.InsertItem(i, &tabitem);
}
m_tabctrl.m_tabdialog[0]->Create(IDD_LINKTAB1, this);
m_tabctrl.m_tabdialog[1]->Create(IDD_LINKTAB2, this);
m_tabctrl.m_tabdialog[2]->Create(IDD_LINKTAB3, this);
@ -81,6 +81,15 @@ BOOL LinkOptions::OnInitDialog(){
}
BOOL LinkOptions::PreTranslateMessage(MSG* pMsg)
{
return m_tabctrl.TranslatePropSheetMsg(pMsg) ? TRUE :
CDialog::PreTranslateMessage(pMsg);
}
BEGIN_MESSAGE_MAP(LinkOptions, CDialog)
//{{AFX_MSG_MAP(LinkOptions)
ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnSelchangeTab1)
@ -205,24 +214,233 @@ void LinkOptions::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
*pResult = 0;
}
IMPLEMENT_DYNAMIC(CMyTabCtrl, CTabCtrl)
BEGIN_MESSAGE_MAP(CMyTabCtrl, CTabCtrl)
ON_NOTIFY_REFLECT(TCN_SELCHANGING, OnSelChanging)
END_MESSAGE_MAP()
BOOL CMyTabCtrl::SubclassDlgItem(UINT nID, CWnd* pParent)
{
if (!CTabCtrl::SubclassDlgItem(nID, pParent))
return FALSE;
ModifyStyle(0, TCS_OWNERDRAWFIXED);
// If first tab is disabled, go to next enabled tab
if (!IsTabEnabled(0)) {
int iTab = NextEnabledTab(0, TRUE);
SetActiveTab(iTab);
}
return TRUE;
}
BOOL CMyTabCtrl::IsTabEnabled(int iTab)
{
if (!lanlink.active && iTab > 0)
return false;
return true;
}
//////////////////
// Draw the tab: mimic SysTabControl32, except use gray if tab is disabled
//
void CMyTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
DRAWITEMSTRUCT& ds = *lpDrawItemStruct;
int iItem = ds.itemID;
// Get tab item info
char text[128];
TCITEM tci;
tci.mask = TCIF_TEXT;
tci.pszText = text;
tci.cchTextMax = sizeof(text);
GetItem(iItem, &tci);
// use draw item DC
CDC dc;
dc.Attach(ds.hDC);
// calculate text rectangle and color
CRect rc = ds.rcItem;
rc += CPoint(1,4); // ?? by trial and error
// draw the text
OnDrawText(dc, rc, text, !IsTabEnabled(iItem));
dc.Detach();
}
//////////////////
// Draw tab text. You can override to use different color/font.
//
void CMyTabCtrl::OnDrawText(CDC& dc, CRect rc,
CString sText, BOOL bDisabled)
{
dc.SetTextColor(GetSysColor(bDisabled ? COLOR_3DHILIGHT : COLOR_BTNTEXT));
dc.DrawText(sText, &rc, DT_CENTER|DT_VCENTER);
if (bDisabled) {
// disabled: draw again shifted northwest for shadow effect
rc += CPoint(-1,-1);
dc.SetTextColor(GetSysColor(COLOR_GRAYTEXT));
dc.DrawText(sText, &rc, DT_CENTER|DT_VCENTER);
}
}
//////////////////
// Selection is changing: disallow if tab is disabled
//
void CMyTabCtrl::OnSelChanging(NMHDR* pnmh, LRESULT* pRes)
{
TRACE("CMyTabCtrl::OnSelChanging\n");
// Figure out index of new tab we are about to go to, as opposed
// to the current one we're at. Believe it or not, Windows doesn't
// pass this info
//
TC_HITTESTINFO htinfo;
GetCursorPos(&htinfo.pt);
ScreenToClient(&htinfo.pt);
int iNewTab = HitTest(&htinfo);
if (iNewTab >= 0 && !IsTabEnabled(iNewTab))
*pRes = TRUE; // tab disabled: prevent selection
}
//////////////////
// Trap arrow-left key to skip disabled tabs.
// This is the only way to know where we're coming from--ie from
// arrow-left (prev) or arrow-right (next).
//
BOOL CMyTabCtrl::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN &&
(pMsg->wParam == VK_LEFT || pMsg->wParam == VK_RIGHT)) {
int iNewTab = (pMsg->wParam == VK_LEFT) ?
PrevEnabledTab(GetCurSel(), FALSE) :
NextEnabledTab(GetCurSel(), FALSE);
if (iNewTab >= 0)
SetActiveTab(iNewTab);
return TRUE;
}
return CTabCtrl::PreTranslateMessage(pMsg);
}
////////////////
// Translate parent property sheet message. Translates Control-Tab and
// Control-Shift-Tab keys. These are normally handled by the property
// sheet, so you must call this function from your prop sheet's
// PreTranslateMessage function.
//
BOOL CMyTabCtrl::TranslatePropSheetMsg(MSG* pMsg)
{
WPARAM key = pMsg->wParam;
if (pMsg->message == WM_KEYDOWN && GetAsyncKeyState(VK_CONTROL) < 0 &&
(key == VK_TAB || key == VK_PRIOR || key == VK_NEXT)) {
int iNewTab = (key==VK_PRIOR || GetAsyncKeyState(VK_SHIFT) < 0) ?
PrevEnabledTab(GetCurSel(), TRUE) :
NextEnabledTab(GetCurSel(), TRUE);
if (iNewTab >= 0)
SetActiveTab(iNewTab);
return TRUE;
}
return FALSE;
}
//////////////////
// Helper to set the active page, when moving backwards (left-arrow and
// Control-Shift-Tab). Must simulate Windows messages to tell parent I
// am changing the tab; SetCurSel does not do this!!
//
// In normal operation, this fn will always succeed, because I don't call it
// unless I already know IsTabEnabled() = TRUE; but if you call SetActiveTab
// with a random value, it could fail.
//
BOOL CMyTabCtrl::SetActiveTab(UINT iNewTab)
{
TRACE("CMyTabCtrl::SetActiveTab\n");
// send the parent TCN_SELCHANGING
NMHDR nmh;
nmh.hwndFrom = m_hWnd;
nmh.idFrom = GetDlgCtrlID();
nmh.code = TCN_SELCHANGING;
if (GetParent()->SendMessage(WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh) >=0) {
// OK to change: set the new tab
SetCurSel(iNewTab);
// send parent TCN_SELCHANGE
nmh.code = TCN_SELCHANGE;
GetParent()->SendMessage(WM_NOTIFY, nmh.idFrom, (LPARAM)&nmh);
return TRUE;
}
return FALSE;
}
/////////////////
// Return the index of the next enabled tab after a given index, or -1 if none
// (0 = first tab).
// If bWrap is TRUE, wrap from beginning to end; otherwise stop at zero.
//
int CMyTabCtrl::NextEnabledTab(int iCurrentTab, BOOL bWrap)
{
int nTabs = GetItemCount();
for (int iTab = iCurrentTab+1; iTab != iCurrentTab; iTab++) {
if (iTab >= nTabs) {
if (!bWrap)
return -1;
iTab = 0;
}
if (IsTabEnabled(iTab)) {
return iTab;
}
}
return -1;
}
/////////////////
// Return the index of the previous enabled tab before a given index, or -1.
// (0 = first tab).
// If bWrap is TRUE, wrap from beginning to end; otherwise stop at zero.
//
int CMyTabCtrl::PrevEnabledTab(int iCurrentTab, BOOL bWrap)
{
for (int iTab = iCurrentTab-1; iTab != iCurrentTab; iTab--) {
if (iTab < 0) {
if (!bWrap)
return -1;
iTab = GetItemCount() - 1;
}
if (IsTabEnabled(iTab)) {
return iTab;
}
}
return -1;
}
void CMyTabCtrl::OnSwitchTabs(void)
{
CRect tabRect, itemRect;
int nX, nY, nXc, nYc, i;
CRect clientRect, wndRect;
int i;
GetClientRect(&tabRect);
GetItemRect(0, &itemRect);
GetClientRect(clientRect);
AdjustRect(FALSE, clientRect);
GetWindowRect(wndRect);
GetParent()->ScreenToClient(wndRect);
clientRect.OffsetRect(wndRect.left, wndRect.top);
nX=itemRect.left+10;
nY=itemRect.bottom+12;
nXc=tabRect.right-itemRect.left-2;
nYc=tabRect.bottom-nY+8;
if(lanlink.active==0) SetCurSel(0);
if(lanlink.active==0)
SetCurSel(0);
for(i=0;i<3;i++){
if(i==GetCurSel()){
m_tabdialog[i]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
m_tabdialog[i]->SetWindowPos(&wndTop, clientRect.left, clientRect.top, clientRect.Width(), clientRect.Height(), SWP_SHOWWINDOW);
} else {
m_tabdialog[i]->ShowWindow(SW_HIDE);
}
@ -242,12 +460,14 @@ void LinkGeneral::OnRadio1()
{
m_type = 0;
lanlink.active = 0;
GetParent()->Invalidate();
}
void LinkGeneral::OnRadio2()
{
m_type = 1;
lanlink.active = 1;
GetParent()->Invalidate();
}
BOOL LinkGeneral::OnInitDialog(){

View File

@ -7,13 +7,35 @@
// LinkOptions.h : header file
//
class CMyTabCtrl : public CTabCtrl
{
class CMyTabCtrl : public CTabCtrl {
DECLARE_DYNAMIC(CMyTabCtrl)
public:
CMyTabCtrl(void);
~CMyTabCtrl(void);
BOOL IsTabEnabled(int iTab); // you must override
BOOL TranslatePropSheetMsg(MSG* pMsg); // call from prop sheet
BOOL SubclassDlgItem(UINT nID, CWnd* pParent); // non-virtual override
// helpers
int NextEnabledTab(int iTab, BOOL bWrap); // get next enabled tab
int PrevEnabledTab(int iTab, BOOL bWrap); // get prev enabled tab
BOOL SetActiveTab(UINT iNewTab); // set tab (fail if disabled)
CDialog *m_tabdialog[3];
void OnSwitchTabs(void);
protected:
DECLARE_MESSAGE_MAP()
afx_msg void OnSelChanging(NMHDR* pNmh, LRESULT* pRes);
// MFC overrides
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
// override to draw text only; eg, colored text or different font
virtual void OnDrawText(CDC& dc, CRect rc, CString sText, BOOL bDisabled);
};
/////////////////////////////////////////////////////////////////////////////
@ -73,6 +95,8 @@ public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(LinkOptions)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL