BBC BASIC for Windows
« Tabs »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 9:56pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Tabs  (Read 875 times)
KenDown
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 181
xx Tabs
« Thread started on: Nov 14th, 2016, 8:44pm »

Hmmmm.

I'm writing a program using tabs (as per the Wiki article http://bb4w.wikispaces.com/Creating+a+tab+control) and it's all working nicely. I click on the different tabs and the right things display on screen.

Now, however, I want to change tabs under control of the program, so that when I click on something in one tab, that tab hides and another tab displays. I can do it easily with

SYS"ShowWindow",!dlg%(3),0
SYS"ShowWindow",!dlg%(0),5

but the second tab is not selected or highlighted or whatever you want to call it. If I click on a third tab, it appears overwritten by dlg%(0), which is not at all nice!

Anyone with any ideas how I can force the second tab to be selected and the first one deselected? I've tried mucking around with the variables currsel% and prevsel% to no avail.
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: Tabs
« Reply #1 on: Nov 15th, 2016, 11:56am »

The short answer is no, I don't know...

There is a PROCSetFocus in winlib5A, which you presumably already have loaded. Does that help?

D
User IP Logged

Zaphod
Guest
xx Re: Tabs
« Reply #2 on: Nov 15th, 2016, 2:48pm »

So each tab has a dialog on it. When changing tabs you close that dialog and open the other, something like this:
Code:
        REM Change to selected tab
        IF CurTab% > -1 PROC_closedialog(Dlg%(CurTab%)) :REM Close old Tab dialog
        PROC_showdialog(Dlg%(TabID%))                   :REM Open new Tab dialog
        CurTab% = TabID%                                :REM update current pointer
 

Then the newly opened dialog default control will have focus.
I think that is what you are asking.

I also found a problem when minimizing the program and restoring it in that the current tab controls are not repainted, no idea why.
I solved this by putting some code in the main loop to detect this situation and reinitialize the current dialog.

Code:
        REM This block is to fix a peculiarity where the current tab dialog does not repaint after being minimized.
        SYS"IsIconic", @hwnd% TO L%       :REM L% non-zero when minimized
        IF L% THEN
          Min%=TRUE                       :REM Window has been minimized
        ELSE                              :REM Window is not minimized now.
          IF Min% PROC_closedialog(Dlg%(CurTab%)): PROC_showdialog(Dlg%(CurTab%))  :REM Just back from being minimized
          Min%=FALSE                      :REM Update flag, effectively a memory of last scanned state.
        ENDIF
 


It may also be necessary to update the data on the current tab as if you had just got to it.
« Last Edit: Nov 15th, 2016, 3:57pm by Zaphod » User IP Logged

KenDown
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 181
xx Re: Tabs
« Reply #3 on: Nov 15th, 2016, 5:44pm »

Actually, no. You don't close any of the dialog boxes! That's the big convenience about tabs: with dialog boxes accessed via buttons or menu options you have to save the contents and close one box, look up another, then return to the first and actually redraw it with the saved contents.

With tabs the dialog boxes stay open and you can skip from one tab to another - one dialog box to another - without saving or redrawing anything. Your data is still there. Wonderfuil!

I'm using the code from the Wiki article and you have this inside the main loop:

IFhTC%>0THEN
SYS"SendMessage",hTC%,&130B,0,0TOcurrsel%
IFcurrsel%<>prevsel%THEN
IFprevsel%>=0SYS"ShowWindow",!dlg%(prevsel%),0
SYS"ShowWindow",!dlg%(currsel%),5
prevsel%=currsel%
PROCtabhelp(currsel%)
ENDIF
ENDIF

It seems to cope with minimising without any problems, but it will not accept automatic changes, as described in my original post.
User IP Logged

Zaphod
Guest
xx Re: Tabs
« Reply #4 on: Dec 8th, 2016, 10:23pm »

I suppose the original questioner solved his problem, but for others here is an example program. It does not do exactly what the original questioner asked for in that it controls the tabs programmatically from buttons in the main window. Changing tabs from within another tab would be a very unusual Windows action.
Secondly, the MSDN text and examples of dialogs in tabs, does exactly as I suggested earlier, and closes the dialogs as the tab changes, which is different from the Wiki article. Both methods are included here, with the Wiki method left as default.
Code:
      INSTALL @lib$+"WINLIB5A"
      INSTALL @lib$+"WINLIB2A"

      REM!WC
      SW_HIDE = 0
      SW_SHOW = 5
      TCM_SETCURSEL = 4876
      _LOGPIXELSX = 88
      TCIF_TEXT = 1
      TCM_GETCURSEL = 4875
      TCM_INSERTITEMA = 4871
      WS_CLIPCHILDREN = &2000000
      WS_CLIPSIBLINGS = &4000000
      _ICC_TAB_CLASSES = 8

      Width%=300 : REM Dialogue box sizes
      Height%=200
      font%=8
      size%=10000

      SYS "GetDeviceCaps", @memhdc%, _LOGPIXELSX TO Dpi%   :REM Find the screen resolution in use
      Scale = Dpi%/96                                      :REM Scale relative to standard 96 dpi

      REM Items in the main window have to be scaled to match the dialog boxes which change with dpi.
      H1%= FN_button(@hwnd%,"Back",20*Scale,380*Scale,60*Scale,40*Scale,201,0)
      H2%= FN_button(@hwnd%,"Fwd",80*Scale,380*Scale,60*Scale,40*Scale,202,0)

      DIM dlg%(2)
      dlg%(0)=FNdefine_diag1
      dlg%(1)=FNdefine_diag2
      dlg%(2)=FNdefine_diag3

      REM Now to find the size of the dialog so we can match the tab control to it. (If needed)
      REM to do this we have to open a dilaog and measure it as the font chnages the size as well!
      PROC_showdialog(dlg%(0))
      DIM rc{l%,t%,r%,b%}
      rc.l% = 0
      rc.r% = Width%
      rc.t% = 0
      rc.b% = Height%
      SYS "MapDialogRect", !dlg%(0), rc{}
      pixx% = rc.r%-rc.l%
      pixy% = rc.b%-rc.t%
      PROC_closedialog(dlg%(0))  :REM Destroy the dialog once we have done with it.

      DIM icex{dwSize%, dwICC%}
      icex.dwSize% = DIM(icex{})
      icex.dwICC% = _ICC_TAB_CLASSES
      SYS "InitCommonControlsEx", icex{}

      ON ERROR SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : END
      Click% = 0
      ON SYS Click% = @wparam% : RETURN


      REM --------------- Create the ControlTab window: ------------------
      hTC% = FN_createwindow(@hwnd%, "SysTabControl32", "", 0, 0, pixx%, pixy%, 0, WS_CLIPSIBLINGS OR WS_CLIPCHILDREN, 0)
      IF hTC% = 0 ERROR 100, "Couldn't create tab control window"

      PROCAdd_Tab(hTC%,"First",0) : REM send add tab message to controltab window
      PROCAdd_Tab(hTC%,"Second",1) : REM send add tab message to controltab window
      PROCAdd_Tab(hTC%,"Third",2) : REM send add tab message to controltab window

      REM Make the tab control the parent of the dialog box!
      !(dlg%(0)!4+8) = hTC%
      !(dlg%(1)!4+8) = hTC%
      !(dlg%(2)!4+8) = hTC%

      REM Dock window
      DIM rc{l%,t%,r%,b%}
      SYS "GetWindowRect", hTC%, rc{}
      SYS "GetWindowLong", @hwnd%, -16 TO style%
      SYS "SetWindowLong", @hwnd%, -16, style% AND NOT &50000
      SYS "AdjustWindowRect", rc{}, style% AND NOT &50000, 0
      SYS "SetWindowPos", @hwnd%, 0, 0, 0, rc.r%-rc.l%, rc.b%-rc.t%+100,102  :REM allow space (100) for controls in main window.

      REM Needed only if dialogs not closed as tab changes, Wiki method.
      PROC_showdialog(dlg%(2)): SYS"ShowWindow", !dlg%(2), SW_HIDE
      PROC_showdialog(dlg%(1)): SYS"ShowWindow", !dlg%(1), SW_HIDE
      PROC_showdialog(dlg%(0))

      cursel% = -1
      REPEAT
        click% = 0
        SWAP click%,Click%
        CASE click% OF
          WHEN 201: IF cursel% >0 THEN  SYS "SendMessage", hTC%, TCM_SETCURSEL, cursel%-1, 0
          WHEN 202: IF cursel% <2 THEN  SYS "SendMessage", hTC%, TCM_SETCURSEL, cursel%+1, 0
        ENDCASE
  
        SYS "SendMessage", hTC%, TCM_GETCURSEL, 0, 0 TO id%
        IF id% <> cursel% THEN
          REM MSDN preferred method closes dialogs. (not Wiki method).
          REM https://msdn.microsoft.com/en-us/library/windows/desktop/hh298366(v=vs.85).aspx
          REM IF cursel% >= 0 PROC_closedialog(dlg%(cursel%))
          REM PROC_showdialog(dlg%(id%))
          REM cursel% = id%
    
          REM With this Wiki method the focus is not transfered to default dialog control automatically.
          IF cursel% >= 0 SYS"ShowWindow", !dlg%(cursel%), SW_HIDE
          SYS"ShowWindow", !dlg%(id%), SW_SHOW
          cursel% = id%
          SYS "GetDlgItem",!dlg%(id%),101 TO H%
          PROC_setfocus(H%)
    
        ENDIF
      UNTIL INKEY(1) = 0

      END

      REM
      -----------------------------------------------------------------

      DEFPROCAdd_Tab(htc%,text$,id%)
      LOCAL cti{}, fn%, res%
      DIM cti{mask%,dwState%,dwStateMask%,pszText%,cchTextMax,iImage,lparam%}
      text$ += CHR$0
      cti.mask%=TCIF_TEXT
      cti.iImage=-1
      cti.pszText%=!^text$
      SYS "SendMessage", htc%, TCM_INSERTITEMA, id%, cti{} TO res%
      IF res% = -1 ERROR 100, "Couldn't send Tab Control info"
      ENDPROC

      REM
      -----------------------------------------------------------------

      DEF FNdefine_diag1
      LOCAL dlg%
      dlg%=FN_newdialog("",0,14,Width%,Height%,font%,size%)
      dlg%!16=&508800C4 : REM remove title bar and make child window
      PROC_static(dlg%,"Test1",100,84,6,20,20,0)
      PROC_editbox(dlg%,"",101,84,30,50,14,0)
      = dlg%

      DEF FNdefine_diag2
      LOCAL dlg%
      dlg%=FN_newdialog("",0,14,Width%,Height%,font%,size%)
      dlg%!16=&508800C4 : REM remove title bar and make child window
      PROC_static(dlg%,"Test2",100,84,6,20,20,0)
      PROC_editbox(dlg%,"",101,84,30,50,14,0)
      = dlg%

      DEF FNdefine_diag3
      LOCAL dlg%
      dlg%=FN_newdialog("",0,14,Width%,Height%,font%,size%)
      dlg%!16=&508800C4 : REM remove title bar and make child window
      PROC_static(dlg%,"Test3",100,84,6,20,20,0)
      PROC_editbox(dlg%,"",101,84,30,50,14,0)
      = dlg%
 


I hope that might be useful for someone. The automatic scaling with dpi has NOT been tested, but i believe it should work.
User IP Logged

KenDown
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 181
xx Re: Tabs
« Reply #5 on: Dec 9th, 2016, 06:38am »

Oh brilliant! That does exactly what I want. It was the

SYS"SendMessage", hTC%, 4876, cursel%, 0

which did it, and no, one doesn't need to close any dialog boxes. Just determine the tab number that you need to open and set cursel% to that, send the message and the required tab opens (which automatically obscures the others).
User IP Logged

Zaphod
Guest
xx Re: Tabs
« Reply #6 on: Dec 9th, 2016, 3:16pm »

Good, I am glad that was useful.

That was:

SYS"SendMessage", hTC%, TCM_SETCURSEL, cursel%, 0

for those that don't memorize the Windows Constants by number.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls