These tab controls work basically ok. Tab number 2 is subclassed so %WM_MOUSEMOVE events can be used to draw a vertical line that moves through the tab page with the mouse.
The problem I'm having is trying to get the "draw a couple lines" graphics in TabSubClassProc() to appear when tab 2 is initially selected. When selecting a different tab, the graphics flash and disappear. I'm sure the %WM_SHOWWINDOW is not appropriate to use here. The graphics are being drawn probably, but the tab control is just being drawn over them immediately after. Is there a message sent when the tab control is finished drawing itself that I can use to trigger my "draw a couple lines" section? Or am I taking care of this in the wrong place?
Thanks,
Todd Wasson
P.S. Oh yes, one more thing! How can I get the tab callback functions (cbTab1,cbTab2,cbTab3) to work? Once they work, can they be used to "draw a couple lines"? Tab 2 should eventually show a graph that gets drawn when it is selected, then the mouse should control a vertical line that scrolls over it.
::TabDDT.INC now included here, thanks to Peter Stephenson.
[This message has been edited by Todd Wasson (edited May 28, 2000).]
Code:
#COMPILE EXE #INCLUDE "commctrl.inc" #INCLUDE "TabDDT.inc" %IDC_TAB = 1000 %IDLABEL1 = 1 GLOBAL hDlg AS LONG GLOBAL hTab AS LONG GLOBAL hTabDlg1 AS LONG GLOBAL hTabDlg2 AS LONG GLOBAL hTabDlg3 AS LONG GLOBAL point AS POINTAPI GLOBAL last_point AS POINTAPI GLOBAL hpen AS LONG GLOBAL hDc AS LONG GLOBAL DefaultTabProc AS LONG DECLARE CALLBACK FUNCTION MainDlgProc DECLARE FUNCTION TabSubClassProc (BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG FUNCTION PBMAIN LOCAL th AS TABHDR LOCAL TEXT AS STRING ' Main dialog DIALOG NEW 0, "DDT - Tab Example",,,400, 300, %WS_SYSMENU OR %WS_MINIMIZEBOX OR %DS_CENTER TO hDlg CONTROL ADD LABEL, hDlg,%IDLABEL1,"-------- ",5,5,60,12,0 ' Tab control hTab = TabCtrl(hDlg, %IDC_TAB, 20, 20, 300, 250) ' Tab - dialog 1 DIALOG NEW hTab, "Tab nr. 1",,,400, 300, %WS_CHILD OR %WS_VISIBLE TO hTabDlg1 ' Tab - dialog 2 DIALOG NEW hTab, "Tab nr. 2",,,400, 300, %WS_CHILD OR %WS_VISIBLE TO hTabDlg2 CONTROL ADD LABEL, hTabDlg2, -1, "This is Tab 2", 5,5,50,14 ' Tab - dialog 3 DIALOG NEW hTab, "Super tab number 3",,,400,300, %WS_CHILD OR %WS_VISIBLE TO hTabDlg3 CONTROL ADD BUTTON, hTabDlg3, 100, "A button",50,50, 90,90 th.lID = %IDC_TAB th.cDialogs = 3 th.DlgHdr(0).hTabDlg = hTabDlg1 th.DlgHdr(0).lpfnCallback = CODEPTR(cbTab1) th.DlgHdr(1).hTabDlg = hTabDlg2 th.DlgHdr(1).lpfnCallback = CODEPTR(cbTab2) th.DlgHdr(2).hTabDlg = hTabDlg3 th.DlgHdr(2).lpfnCallback = CODEPTR(cbTab3) InitTabControl hDlg, th DIALOG SHOW MODAL hDlg CALL MainDlgProc END FUNCTION CALLBACK FUNCTION MainDlgProc SELECT CASE CBMSG CASE %WM_INITDIALOG DefaultTabProc = SetWindowLong(hTabDlg2, %GWL_WNDPROC, CODEPTR(TabSubClassProc)) CASE %WM_NOTIFY OnTabNotify CBHNDL, CBLPARAM ' CASE %WM_COMMAND ' SELECT CASE LOWRD(CBWPARAM) ' END SELECT END SELECT END FUNCTION CALLBACK FUNCTION cbTab1 SELECT CASE CBMSG CASE %WM_INITDIALOG CASE %WM_COMMAND SELECT CASE LOWRD(CBWPARAM) END SELECT END SELECT END FUNCTION CALLBACK FUNCTION cbTab2 SELECT CASE CBMSG CASE %WM_INITDIALOG CASE %WM_COMMAND SELECT CASE LOWRD(CBWPARAM) END SELECT END SELECT END FUNCTION CALLBACK FUNCTION cbTab3 SELECT CASE CBMSG CASE %WM_INITDIALOG CASE %WM_COMMAND SELECT CASE LOWRD(CBWPARAM) END SELECT END SELECT END FUNCTION FUNCTION TabSubClassProc (BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, _ BYVAL wParam AS LONG, BYVAL lParam AS LONG) EXPORT AS LONG IF wMsg= %WM_SHOWWINDOW THEN Point.x=0 Point.y=0 ''Draw a couple lines hDC = GetDC(hTabDlg2) hpen = CreatePen (%PS_SOLID,2,RGB(255,255,255)) SelectObject hDC,hpen SetROP2 hDC, %R2_COPYPEN MoveTo hDC, 100,200 LineTo hDC, 200,300 MoveTo hDC, 300,50 LineTo hDC, 50,50 ReleaseDC hTabDlg2, hDc DeleteObject hpen END IF IF wMsg= %WM_MOUSEMOVE THEN Last_Point=Point GetCursorPos Point TEXT$="X: "+STR$(POINT.X)+" Y: "+STR$(POINT.Y) CONTROL SET TEXT hdlg,%IDLABEL1, TEXT$ hDC = GetDC(hTabDlg2) hpen = CreatePen (%PS_SOLID,2,RGB(255,255,255)) SelectObject hDC,hpen SetROP2 hDC, %R2_XORPEN MoveTo hDC, LAST_POINT.X-137,0 LineTo hDC, LAST_POINT.X-137,350 MoveTo hDC, POINT.X-137,0 LineTo hDC, POINT.X-137,350 ReleaseDC hTabDlg2, hDc DeleteObject hpen ELSE FUNCTION = CallWindowProc(DefaultTabProc, hWnd, wMSg, WParam, Lparam) END IF END FUNCTION '------- TabDDT.inc --------------- '---------------------------------- ' DDT Tab Control ' Peter Stephensen 2000 '---------------------------------- %TRUE=1 #IF NOT %DEF(%TAB_DLGMAX) %TAB_DLGMAX = 10 ' Maximal number of tab items #ENDIF #IF NOT %DEF(%TAB_LINES) %TAB_LINES = 2 ' Number of lines in Tab control. Set this to 2 #ENDIF ' if multiline-style is used TYPE DLGHDR hTabDlg AS LONG lpfnCallback AS LONG END TYPE TYPE TABHDR lID AS LONG ' Integer ID for Tab Control cDialogs AS LONG ' Number of dialogs DlgHdr(%TAB_DLGMAX) AS DLGHDR ' Dialogs END TYPE DECLARE SUB TabDisplay(hDlg AS LONG,TabID AS LONG,newTab AS LONG) GLOBAL pth AS TABHDR PTR FUNCTION TabCtrl(BYVAL hDlg AS LONG, BYVAL ID AS LONG, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL xx AS LONG, BYVAL yy AS LONG) AS LONG LOCAL hTab AS LONG IF hDlg = 0 THEN EXIT FUNCTION CONTROL ADD "SysTabControl32", hDlg, ID, "", x, y, xx, yy, %WS_CHILD OR %WS_VISIBLE CONTROL HANDLE hDlg, ID TO hTab FUNCTION = hTab END FUNCTION FUNCTION InitTabControl(hDlg AS LONG, th AS TABHDR) AS LONG LOCAL tie AS TC_ITEM LOCAL rcTab AS RECT LOCAL i AS LONG LOCAL hInst AS LONG LOCAL hWndTab AS LONG LOCAL zBuffer AS ASCIIZ*128 InitCommonControls pth = LocalAlloc(%LPTR, SIZEOF(@pth)) hInst = GetModuleHandle(BYVAL 0) hWndTab = GetDlgItem(hDlg,th.lID) GetClientRect hwndTab,rcTab ' Add a tab for each of the child dialog boxes. FOR i = 0 TO th.cDialogs-1 tie.mask = %TCIF_TEXT OR %TCIF_IMAGE tie.iImage = -1 GetWindowText th.DlgHdr(i).hTabDlg, zBuffer, 128 tie.pszText = VARPTR(zBuffer) TabCtrl_InsertItem hwndTab, i, tie MoveWindow th.DlgHdr(i).hTabDlg, _ 4, _ %TAB_LINES*23, _ rcTab.nRight-rcTab.nLeft-11, _ rcTab.nBottom-rcTab.nTop-%TAB_LINES*23-3, _ %TRUE NEXT i @pth = th TabDisplay hDlg, th.lID, 0 END FUNCTION SUB TabDisplay(hDlg AS LONG,TabID AS LONG, TabIndex AS LONG) STATIC PrevTabIndex AS LONG LOCAL i AS LONG IF PrevTabIndex THEN ShowWindow PrevTabIndex, %SW_HIDE END IF IF pth = 0 THEN EXIT SUB ShowWindow @pth.DlgHdr(TabIndex).hTabDlg, %SW_SHOW PrevTabIndex = @pth.DlgHdr(TabIndex).hTabDlg END SUB SUB OnTabNotify (BYVAL hDlg AS LONG, BYVAL lParam AS LONG ) LOCAL lpNmh AS NMHDR PTR IF pth = 0 THEN EXIT SUB lpNmh = lParam SELECT CASE @lpNmh.Code CASE %TCN_LAST TO %TCN_FIRST SELECT CASE @lpNmh.idFrom CASE @pth.lID SELECT CASE @lpNmh.Code CASE %TCN_SELCHANGE TabDisplay hDlg, @pth.lID, TabCtrl_GetCurSel(GetDlgItem(hDlg,@pth.lID)) END SELECT END SELECT END SELECT END SUB
Thanks,
Todd Wasson
P.S. Oh yes, one more thing! How can I get the tab callback functions (cbTab1,cbTab2,cbTab3) to work? Once they work, can they be used to "draw a couple lines"? Tab 2 should eventually show a graph that gets drawn when it is selected, then the mouse should control a vertical line that scrolls over it.
::TabDDT.INC now included here, thanks to Peter Stephenson.
[This message has been edited by Todd Wasson (edited May 28, 2000).]
Comment