• Welcome to Jose's Read Only Forum 2023.

TabControl 32/64

Started by Pierre Bellisle, December 30, 2022, 08:01:06 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Pierre Bellisle

Hi Charles!

Here is something unexpected.

When compiling ...\Oxygen\o2\demos\WinDynDialogs\TabControl.o2bas as is in 32 bit, the exe works fine.

Compiling in 64 bit, I got a sure GPF that occur after EndDialog(hDlg, 0).
If I REMout this line ts.lParam= Createmodelessdialog(hdlg,@Tab2Proc,0) then I got no more GPF.
Tested under Windows 7, not yet under Windows 10.

Have any idea of what's going under the hood?


Roland Stowasser

Hi Pierre,

I believe, I have no problems with Windows 10. The program shows up in the task manager, and when I exit it (either System X, or menu: Close, or Alt-F4), the program disappears from the task manager. And I can also change the tabs and fill the edits and checkbox without memory leaks. However, I compile the program with only the filename as an argument, like so:

'modified from a fsw example in the FBEdit samples

$ filename "TabControl.exe"
'uses rtl32
uses rtl64

I do not remember that there were problems under Windows 7, but maybe I forgot something. There are several EndDialog statements. Does GPF occur in all cases?


Pierre Bellisle

Thank Roland,
I will test this under Windows 10.

Here, under Windows 7, after a reboot, 64bit version still GPF...

Pierre Bellisle


Test result:
First Windows 7, GPF every time
Second Windows 7, no GPF
Third Windows 7, no GPF
Windows 8, GPF every time
Windows 10, no GPF

I will investigate more, the machines that GPF are in good shape, so, it will be welcome if anayone feel like testing...


Zlatko Vid

you should look into my awinh037.inc include file
there is how i made tab control

Pierre Bellisle

Many thanks Zlatko!
I will read your awinh037.inc include.

Also, I must say that I'm interested to find why it GPF?
Problem seems to be in Oxygen\o2\inc\Dialogs.inc / CreateModelessDialog() and sub Dialog().
Probably an invalid freememory() call caused by calling CreateModelessDialog twice.
I got to stop for now but I will look at it later...

Zlatko Vid

well i don't use Dialogs then Windows
here is part:
Function SetTabControl (byval _tbhwnd as INT,byval _tx as INT,byval _ty as INT,byval _tw as INT,byval _th as INT,byval _tbflag as INT,byval _ex as INT,byval cID as INT) As INT
INT _hfont
  If _tbflag=0
  End If
  hTabControl = CreateWindowEx(_ex,"SysTabControl32","",_tbflag,_tx,_ty,_tw,_th,_tbhwnd,cID,0,0)
_hfont = GetStockObject(17)
SendMessage hTabControl,WM_SETFONT,_hfont,0
  UpdateWindow _tbhwnd
Function = hTabControl
End Function
Function AddTab (byval hwnd as INT ,byval tbpos as INT,byval tbtext as String ) as INT
tie.pszText= strptr(tbtext)
tie.iImage = -1

End Function
Function SetTabText (cntID as INT,tbIndex as INT,tabText as String)
tie.pszText= strptr(tabText)
tie.iImage = -1
End Function

SUB SetSelectedTab (cntID as INT,index as INT)
Sendmessage (cntID,TCM_SETCURSEL,index,0)

'Return tbIndex
End Sub

Function GetSelectedTab (cntID as INT) as INT
INT tbIndex
tbIndex = Sendmessage (cntID,TCM_GETCURSEL,0,0)

Return tbIndex
End Function

Function GetTabText (cntID as INT,tbIndex as INT) as string
string tabText=Space(256)
tie.pszText = strptr tabText
tie.cchTextMax = 256
tie.iImage = -1
Sendmessage (cntID,TCM_GETITEM,tbIndex,&tie)
Return tabText
End Function
Function GetTabCount (cntID as INT) as INT
INT tbCount
tbCount = Sendmessage (cntID,TCM_GETITEMCOUNT,0,0)
Return tbCount
End Function
Function DeleteTab (cntID as INT, index as INT ) as INT
Sendmessage (cntID,TCM_DELETEITEM,index,0)
Return 0
End Function

so check this with RTL64.inc

Zlatko Vid

and why you insist on Dialogs...hmmm there is no any advantage over Window class
here is example by Charles i guess and work well so you can compare both

includepath "$/inc/"
include "minwin.inc"

'% HWND_TOP       0
'% SWP_NOSIZE     1
'% SWP_NOMOVE     2

% TCIF_TEXT       1


type NMHDR
  sys hwndFrom,idFrom
  int code
end type

  int   mask,dwState,dwStateMask
  char* pszText
  int   cchTextMax,iImage
  sys   lParam
end type

sys hWndMain,hWndTab,hwnd0,hwnd01,hwnd1,hwnd2,hwnd3,hinst

Declare Sub InitCommonControls lib "comctl32.dll" ()

function MakeWindow(sys num)
hwnd0=CreateWindowEx(0,"edit", "text "+num+1, WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
                     0,28,300, 300,
                     hwndTab, NULL, hinst, NULL)
end function

function WndProc(HWND hwnd, UINT ms, wParam, lParam) as sys callback
static int iPage=-1
select ms
case WM_CLOSE   : DestroyWindow(hwnd)
case WM_DESTROY : PostQuitMessage(0)
case WM_NOTIFY  :
  NMHDR hdr at lparam
  select hdr.code
    'leaving tab
  case -2
    'selected tab
    int i = SendMessage(hwndtab,TCM_GETCURSEL,0,0)
    if i <> iPage
      DestroyWindow hwnd0
    end if
  end select
case else : return DefWindowProc(hwnd, ms, wParam, lParam)
end select
end function

function WinMain(sys hInstance, hPrevInstance, char*lpCmdLine, int nCmdShow) as sys
sys        hwnd
MSG        ms


wc.cbSize        = sizeof(WNDCLASSEX)
wc.style         = 0
wc.lpfnWndProc   = @WndProc
wc.cbClsExtra    = 0
wc.cbWndExtra    = 0
wc.hInstance     = hInstance
wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION)
wc.hCursor       = LoadCursor(NULL, IDC_ARROW)
wc.hbrBackground = COLOR_WINDOW+1
wc.lpszMenuName  = NULL
wc.lpszClassName = strptr "myWindowClass"
wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION)


hwndMain = CreateWindowEx(WS_EX_CLIENTEDGE,"myWindowClass","The title of my window",
                          CW_USEDEFAULT, CW_USEDEFAULT, 350, 300,
                          NULL, NULL, hInstance, NULL)
ShowWindow(hwndMain, nCmdShow)
hwndTab=CreateWindowEx(0,"SysTabControl32", "",
                       0, 0, 300, 250,
                       hwndMain, NULL, hInstance, NULL)
tie.mask = TCIF_TEXT
tie.pszText = "Hi1"
SendMessage hwndTab,TCM_INSERTITEM,0,@tie
tie.mask = TCIF_TEXT
tie.pszText = "Hi2"
SendMessage hwndTab,TCM_INSERTITEM,1,@tie
tie.mask = TCIF_TEXT
tie.pszText = "Hi3"
SendMessage hwndTab,TCM_INSERTITEM,2,@tie
tie.mask = TCIF_TEXT
tie.pszText = "Hi4"
SendMessage hwndTab,TCM_INSERTITEM,3,@tie

SendMessage hwndTab,TCM_SETCURSEL,3,0
'print SendMessage hwndTab,TCM_GETCURSEL,0,0

ShowWindow(hwndTab, SW_SHOW)

while(GetMessage(&ms, NULL, 0, 0) > 0)
return ms.wParam
end function

char *cmdline
sys inst
inst=GetModuleHandle 0
'call Main function ..heh oK?
WinMain (inst,0,cmdline,SW_NORMAL)

Pierre Bellisle

I do not insist on using Dialog, I use both, as you ca see in those two Splitter Window examples or in this FreeBASIC TrackBar example.
By trying to find out why there is a GPF, I read O2 code and I learn.
Plus, I am sometime curious...

Found it !
Oxygen\o2\inc\Dialogs.inc -> function CreateModalDialog() -> freememory lpdt
was called more than once with the same memory address so the GPF.
I added a flag variable to remember so that freememory won't append more than once...

Roland Stowasser

Hi Pierre,

unfortunately I don't have access to Windows 7 at the moment, my friends have all switched to a higher operating system. While I don't understand why this error is not noticeable in Win 10, your objection is logical. Did you modify Dialogs.inc?
There are freememory statements in function CreateModalDialog, function CreateModelessDialog, sub Dialog. I used a variable g_lpdtptr in sub Dialog, and I thought it would cover all cases but that doesn't seem to be the case.
It's been a while since I dealt with Dialogs.inc - Charles helped me to make it work in 64-bit as well. But I'm just a hobbyist, and improvements in Dialogs.inc are certainly needed. It is mostly derived from Freebasic, the link of dialogs.bas is given in the include file, and I noticed that you participated in the discussion too. So maybe you may find other vulnerabilities?


Zlatko Vid

QuoteI don't have access to Windows 7 at the moment, my friends have all switched to a higher operating system

what a heck your friends OS have with OS you use on your computer
come on Roland ...what kind of excuse is this ?

I am using win7_64bit ...but i compile my apps as 32bit --so i don't use RTL64.inc

I am not sure which example you use ,because you said ..something is wrong
with include file ?
so i can only guess which one is ??? 

Zlatko Vid


i found example TabControl under demos\WinDynDialogs\tabcontrol.o2bas

so do you try to compile it as JIT or as standalone using RTL-s ?

1.test 1...compiled as JIT and this example work well
i am not sure what mean GPF ?

2. test 2 ...but when i uncomment and use rtl64.inc and compile ,i receive okay! ..that is fine
but when i try to run then i get nothing ...
i also try to run executable from folder ..again same case ..not respond
i look into task manager ...nothing is hangin in memory
so yes something is wrong

3 ...and yes when is compiled with rtl32 then program work properly
so i am not sure what might be wrong with dialogs.inc
i can't find your variable 

4...ahh ok i found it
but one thing i don't understand that
lpdt is optional parameter
then is free by
freememory lpdt
in both functions

i don't see such a things in C based examples with Dialogs
in genaral i find it over- complicated for nothing

Zlatko Vid

no mather what i do add or remove this program compile but not run
using RTL64.inc on my win7_64bit

Zlatko Vid

Quotewas called more than once with the same memory address so the GPF.
I added a flag variable to remember so that freememory won't append more than once...

but how you do that ?
what flag?

Zlatko Vid

In my include i am using this :

mask as int
res1 as int
res2 as int
pszText as INT
cchTextMax as int
iImage as int
lParam as int

and in Dialog TabControl example  is used :

  int   mask,dwState,dwStateMask
  char* pszText
  int   cchTextMax,iImage
  sys   lParam
end type

so my question is why is different ?