• 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?

Regards,
Pierre

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?

Roland 


Pierre Bellisle

Thank Roland,
I will test this under Windows 10.

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

Pierre Bellisle

Ok,

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...

Regards,
Pierre


Zlatko Vid

Piere
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
    _tbflag=WS_CHILD | WS_VISIBLE| TCS_HOTTRACK
  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
'=====================================================================================
'AddTab
Function AddTab (byval hwnd as INT ,byval tbpos as INT,byval tbtext as String ) as INT
TC_ITEM tie
tie.mask=1
tie.pszText= strptr(tbtext)
tie.cchTextMax=Len(tbtext)
tie.iImage = -1
SendMessage(hWnd,0x1307,tbpos,&tie)

End Function
'=====================================================================================
Function SetTabText (cntID as INT,tbIndex as INT,tabText as String)
TC_ITEM tie
tie.mask=1
tie.pszText= strptr(tabText)
tie.cchTextMax=Len(tabtext)
tie.iImage = -1
SendMessage(cntID,TCM_SETITEM,tbIndex,&tie)
Return
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)
TC_ITEM tie
tie.mask=1
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
'% HWND_BOTTOM    1
'% SWP_NOSIZE     1
'% SWP_NOMOVE     2
'% SWP_SHOWWINDOW 0x40

% TCIF_TEXT       1
% TCN_SELCHANGE   -551
% TCN_SELCHANGING -552
% TCM_INSERTITEM  0x1307
% TCM_GETCURSEL   0x130B
% TCM_SETCURSEL   0x130C

% COLOR_WINDOW    5

type NMHDR
  sys hwndFrom,idFrom
  int code
end type

type TCITEM
  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
  case TCN_SELCHANGING
    'leaving tab
  case -2
    'selected tab
    int i = SendMessage(hwndtab,TCM_GETCURSEL,0,0)
    if i <> iPage
      iPage=i
      DestroyWindow hwnd0
      MakeWindow(iPage)
    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
===================================================================================
WNDCLASSEX wc
sys        hwnd
MSG        ms

hinst=hInstance

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)

rg=RegisterClassEx(&wc)


hwndMain = CreateWindowEx(WS_EX_CLIENTEDGE,"myWindowClass","The title of my window",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT, 350, 300,
                          NULL, NULL, hInstance, NULL)
ShowWindow(hwndMain, nCmdShow)
UpdateWindow(hwndMain)
InitCommonControls()
hwndTab=CreateWindowEx(0,"SysTabControl32", "",
                       WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
                       0, 0, 300, 250,
                       hwndMain, NULL, hInstance, NULL)
TCITEM tie
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)
UpdateWindow(hwndTab)

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


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

Pierre Bellisle

#8
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?

Roland


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

Piere
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

#11
second

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

well...
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 :

TYPE TC_ITEM
mask as int
res1 as int
res2 as int
pszText as INT
cchTextMax as int
iImage as int
lParam as int
End TYPE

and in Dialog TabControl example  is used :

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

so my question is why is different ?