Author Topic: theForger's Tutorials revised  (Read 11704 times)

0 Members and 1 Guest are viewing this topic.

José Roca

  • Guest
Re: theForger's Tutorials revised
« Reply #15 on: March 21, 2018, 03:31:41 PM »
The default alignment for structures in 32 bit is 4 bytes (a DWORD). This is why after

Code: [Select]
   fsState    as byte
   fsStyle    as byte

we need to fill two bytes more (bReserved) to keep the 4 bytes alignment.

But in 64 bit, the default alignment is 8 bytes (a QUAD). Therefore bReserved must be 6 bytes to keep the 8 bytes alignment.

BTW the worst thing that you can do to translate C++ structures or API functions is to use VB declares as a guide. VB was not designed for API coders.


Aurel

  • Guest
Re: theForger's Tutorials revised
« Reply #16 on: March 21, 2018, 03:36:46 PM »
Quote
You were curious why your structures are so lopsided -- I answered.

No you don't know because I don't show what i use in original version.

And i really don't know about what kind of f**** C prototypes you think  :o
If you think that i don't know to read  and translate some simple C code about win32
then you wrong.
And you constantly talk about things i know.
Of course i don't want to argue with you at all but please ignore my posts..
so ok?

Mike Lobanovsky

  • Guest
Re: theForger's Tutorials revised
« Reply #17 on: March 21, 2018, 03:39:32 PM »
Got it Aurel. And keep on holding back your sources. You know why.

Out.

Aurel

  • Guest
Re: theForger's Tutorials revised
« Reply #18 on: March 21, 2018, 03:40:28 PM »
Thanks Jose  :)

Do you see Mike who know how to explain things!

Arnold

  • Guest
Re: theForger's Tutorials revised
« Reply #19 on: March 21, 2018, 03:47:57 PM »
Hi  Aurel,

I used the beta release of OxygenBasic. I compiled each program with a 32-bit computer as 32-bit and with a 64-bit computer as 64-bit. If you use corewin.inc with A43, this is a little bit like using sparks of a Porsche in a Mercedes Benz car.

José is very right with the TBBUTTON structure. With my first attempt I only tried to create 32-bit exes and this time I forgot to check the types, which I must catch up. At that time I also did not know about mode64bit:

Code: [Select]
type TBBUTTON
  int       iBitmap
  int       idCommand
  byte      fsState
  byte      fsStyle
#ifdef mode64bit
  byte      bReserved[6]
#else 
  byte      bReserved[2]
#endif
  sys       dwData   
  sys       iString
end type

I am not quite sure about iString, but I think it is a pointer. Perhaps dwData too. It must be tested. That the structure worked in 64-bit happened by chance, I did not use dwData or iString in the example. There are some more structures which must be examined.

Roland

Edit: José, you were faster than me with dwData. Thank you.

« Last Edit: March 21, 2018, 06:08:32 PM by Arnold »

José Roca

  • Guest
Re: theForger's Tutorials revised
« Reply #20 on: March 21, 2018, 03:59:07 PM »
Despite the name used, dwData is also a pointer, so you should also use sys instead of dword.

Charles Pegge

  • Guest
Re: theForger's Tutorials revised
« Reply #21 on: March 21, 2018, 04:15:32 PM »
José, Just to clarify:

Sys is a generic integer type, as you say. It is not specifically a pointer, but is wide enough to hold one on either platform. Generally speaking, it's sign can be disregarded. Due to twos-complement arithmetic, you can safely add and subtract values from the pointer.

The C member alignment rules, which I endeavour to follow, require that 8 bit members have 8bit alignment, 16bit members have 16bit alignment and so forth.

When a structure is inherited, it is aligned in the main structure according to its largest primitive member. For example: if the inherited structure contains a double as its largest primitive, then the structure must align to 64 bits within the main structure.

Oxygen also supports packed types, using 'packed' as a prefix.

Arnold

  • Guest
Re: theForger's Tutorials revised
« Reply #22 on: March 21, 2018, 06:04:17 PM »
Hi Charles,

in examples\WINGUI\Toolbar1.o2bas I found this solution:

Code: OxygenBasic
  1. % _WIN32
  2.  
  3. typedef struct {
  4.   sys     hInst;
  5.   sys     nID;
  6. } TBADDBITMAP, *LPTBADDBITMAP;
  7.  
  8. #ifdef _WIN32
  9.  %n 2
  10. #else
  11.  %n 6
  12. #endif
  13.  
  14. typedef struct {
  15.   int       iBitmap;
  16.   int       idCommand;
  17.   BYTE      fsState;
  18.   BYTE      fsStyle;
  19.   BYTE      bReserved[n];
  20.   sys   dwData;
  21.   sys   iString;
  22. } TBBUTTON, *PTBBUTTON, *LPTBBUTTON;
  23.  

Can my way of using mode64bit be applied too?  It looks so smart.

Roland

Aurel

  • Guest
Re: theForger's Tutorials revised
« Reply #23 on: March 21, 2018, 09:47:21 PM »
Arnold

I use OxygenBasicProgress not A043 just because i want to try CoreWin.inc
Also i use 32bit on win7 and i don't care to much about 64bit yet.
My problems start when i remove  bind()  from awinh035 and declare api function in usual way.
So combination of o2 internal changes and removing things create problem in controls creation.

thanks again
and all best

 :)


Charles Pegge

  • Guest
Re: theForger's Tutorials revised
« Reply #24 on: March 21, 2018, 11:21:32 PM »
Hi Roland,

The n padding is not required because sys will automatically align upward to a 32bit or 64bit block within the structure, depending on its width.

Many thanks for the tutorials. I have not had a chance to look at them yet.

Arnold

  • Guest
Re: theForger's Tutorials revised
« Reply #25 on: March 22, 2018, 01:21:52 AM »
Hi Charles,

I tried this little code and I am not quite sure how I should interpret the results:

Code: [Select]
$ filename "TBBUTTON.exe"

'uses RTL32
'uses RTL64

use console

type TBBUTTON
  int       iBitmap
  int       idCommand
  byte      fsState
  byte      fsStyle
'#ifdef mode64bit 
  byte      bReserved[6]
'#else 
''  byte      bReserved[2]
'#endif
  sys       dwData   
  sys       iString
end type

printl "sizeof  TBBUTTON " sizeof(TBBUTTON)
printl "spanof  TBBUTTON " spanof(TBBUTTON)
printl "countof TBBUTTON " countof(TBBUTTON)
printl
TBBUTTON tbb[3]
printl "sizeof  tbb " sizeof(tbb)
printl "spanof  tbb " spanof(tbb)
printl "countof tbb " countof(tbb)
printl

type TBBUTTON
  int       iBitmap
  int       idCommand
  byte      fsState
  byte      fsStyle
'#ifdef mode64bit 
''  byte      bReserved[6]
'#else 
  byte      bReserved[2]
'#endif
  sys       dwData   
  sys       iString
end type

printl "sizeof  TBBUTTON " sizeof(TBBUTTON)
printl "spanof  TBBUTTON " spanof(TBBUTTON)
printl "countof TBBUTTON " countof(TBBUTTON)
printl
TBBUTTON tbb[3]
printl "sizeof  tbb " sizeof(tbb)
printl "spanof  tbb " spanof(tbb)
printl "countof tbb " countof(tbb)
printl

type TBBUTTON
  int       iBitmap
  int       idCommand
  byte      fsState
  byte      fsStyle
#ifdef mode64bit 
  byte      bReserved[6]
#else 
  byte      bReserved[2]
#endif
  sys       dwData   
  sys       iString
end type

printl "sizeof  TBBUTTON " sizeof(TBBUTTON)
printl "spanof  TBBUTTON " spanof(TBBUTTON)
printl "countof TBBUTTON " countof(TBBUTTON)
printl
TBBUTTON tbb[3]
printl "sizeof  tbb " sizeof(tbb)
printl "spanof  tbb " spanof(tbb)
printl "countof tbb " countof(tbb)
printl

printl "Enter ... " : waitkey

I used a)bReserved[6], b)bReserved[2], c)distinguish 32/64 bit.
In particular I am not sure if I will get the correct position of dwData, iString in each case? (I have not yet tried this)

I assume it does not harm if I differentiate between 32/64 bit? There are some more structures where MSDN makes a difference between 32/64 bit.

Roland

Charles Pegge

  • Guest
Re: theForger's Tutorials revised
« Reply #26 on: March 22, 2018, 02:49:29 AM »
Hi Roland,

You can inspect the compiler's view of TBBUTTON using #recordof. It takes a little interpretation:

Code: [Select]
'2018-03-22 T 10:42:52
'MEMBER PADDING 32BIT/64BIT
$filename "t.exe"
'uses rtl64
type TBBUTTON
  int       iBitmap
  int       idCommand
  byte      fsState
  byte      fsStyle
'#ifdef mode64bit
'  byte      bReserved[6]
'#else
'  byte      bReserved[2]
'#endif
  sys       dwData   
  sys       iString
end type
#recordof "T.TXT"  TBBUTTON

t.txt
Code: [Select]
-3
--------
20
--------
0
--------
0
--------
0
--------
4
--------
0
--------
0
--------
tbbutton
--------
ibitmap 4 0 0 1 AA , int
idcommand 4 4 0 1 AA , int
fsstate 1 8 0 1 AA , byte
fsstyle 1 9 0 1 AA , byte
dwdata 4 12 0 1 AA , sys
istring 4 16 0 1 AA , sys

--------

--------

--------


Arnold

  • Guest
Re: theForger's Tutorials revised
« Reply #27 on: March 23, 2018, 08:28:18 AM »
Hi Charles,

Thank you for pointing to the #recordof command. Hopefully I have understood it a little bit. But I can see if I use bReserved[2] or comment out the bReserved[] statements that I will find dwData at the same position in Win32 and at the same position in Win64. So if I respect the types and use the Win32 values for padding then I should have no problems with Win64.

Oddly enough I did not find more structures of this kind although I was sure there are some. I only found structures with different member types when using Win32 or Win64. But this could be checked when this case will occur.

Roland

Arnold

  • Guest
Re: theForger's Tutorials revised
« Reply #28 on: March 23, 2018, 11:41:36 AM »
These are the first two examples of theForger in short form. There should be no problem to understand them.

simple_window1.o2bas:
Code: OxygenBasic
  1. $ filename "simple_window1.exe"
  2.  
  3. 'uses rtl32
  4. uses rtl64
  5.  
  6. uses WinUtil
  7.  
  8.  
  9. MainWindow 240,120,WS_OVERLAPPEDWINDOW
  10.  
  11.  
  12. function WndProc(sys hwnd, uMsg, wParam, lParam) as sys callback
  13.  
  14.     select uMsg
  15.    
  16.         case WM_CLOSE
  17.             DestroyWindow(hwnd)
  18.        
  19.         case WM_DESTROY
  20.             PostQuitMessage(0)
  21.        
  22.         case else
  23.             return DefWindowProc(hwnd, uMsg, wParam, lParam)
  24.            
  25.     end select
  26.    
  27.     return 0
  28. end function
  29.  

window_click1.o2bas:
Code: OxygenBasic
  1. $ filename "window_click1.exe"
  2.  
  3. 'uses rtl32
  4. uses rtl64
  5.  
  6. uses WinUtil
  7.  
  8. sys hInstance=inst
  9.  
  10. MainWindow 240,120,WS_OVERLAPPEDWINDOW
  11.  
  12.  
  13. function WndProc(sys hwnd, Msg, wParam, lParam) as sys callback
  14.  
  15.     select Msg
  16.    
  17.         case WM_LBUTTONDOWN
  18.             zstring szFileName[MAX_PATH]
  19.  
  20.             GetModuleFileName(hInstance, szFileName, MAX_PATH)
  21.             MessageBox(hwnd, szFileName, "This program is:", MB_OK or MB_ICONINFORMATION)
  22.    
  23.         case WM_CLOSE
  24.             DestroyWindow(hwnd)
  25.        
  26.         case WM_DESTROY
  27.             PostQuitMessage(0)
  28.        
  29.         case else
  30.             return DefWindowProc(hwnd, Msg, wParam, lParam)
  31.            
  32.     end select
  33.    
  34.     return 0
  35. end function
  36.  

Edit: I noticed that copying the code into an editor works, so I only attach the batch files
« Last Edit: March 24, 2018, 02:39:07 AM by Arnold »

Arnold

  • Guest
Re: theForger's Tutorials revised
« Reply #29 on: March 24, 2018, 06:57:57 AM »
Hi Charles,

I am trying to code theForger example 7:dlg_one using winutil.inc and a in-memory dialog. This does work quite nice in JIT mode, but if I try to compile the example to exe, I will get this error:

Linker found unidentified names: ::guistate level 0

I explored the files of Oxygenbasic for guistate, but I can only find it in winutil.inc. As there are some more examples which include winutil.inc, I do not know what I am doing wrong. Can I satisfy Oxygenbasic in some way?

Roland

Edit: Incredible. I was so happy to apply namespace, and now that it is necessary, I forgot about it. But now the example works fine. I can also create Menus à la resource. Oxygen is great!


dlg_one1.o2bas
Code: OxygenBasic
  1. $ filename "dlg_one1.exe"
  2.  
  3.  
  4. 'uses rtl32
  5. uses rtl64
  6.  
  7. '% review
  8.  
  9. uses winutil
  10. uses dialogs
  11. namespace
  12.  
  13. # autodim off
  14.  
  15. % DS_MODALFRAME=128
  16.  
  17.  
  18. #ifndef IDC_STATIC
  19. #define IDC_STATIC (-1)
  20. #endif
  21.  
  22. #define IDR_MYMENU      101
  23. #define IDD_ABOUT       102
  24. #define ID_FILE_EXIT    40001
  25. #define ID_HELP_ABOUT   40002
  26.  
  27.  
  28. declare sub initMenu(sys hWnd)
  29.  
  30.  
  31. MainWindow 240, 120,WS_OVERLAPPEDWINDOW
  32.  
  33.  
  34. function DialogProc(sys hDlg, Message, wParam, lParam) as bool callback
  35.  
  36.   select case Message
  37.  
  38.     case WM_INITDIALOG
  39.       return true
  40.  
  41.     case WM_COMMAND
  42.        select case loword(wParam)
  43.          case IDOK
  44.             EndDialog( hDlg, null)
  45.             MessageBox(null, "Dialog exited with IDOK.", "Notice",
  46.                        MB_OK or MB_ICONINFORMATION)                    
  47.          case IDCANCEL
  48.             EndDialog( hDlg, null )
  49.             MessageBox(null, "Dialog exited with IDCANCEL.", "Notice",
  50.                        MB_OK or MB_ICONINFORMATION)
  51.        end select
  52.      
  53.     case WM_CLOSE
  54.        EndDialog( hDlg, null )
  55.                
  56.   end select
  57.  
  58.   return 0
  59. end function    
  60.  
  61.  
  62. function WndProc(sys hwnd, Message, wParam, lParam) as sys callback
  63.  
  64.     select Message
  65.         case WM_CREATE
  66.            initMenu(hwnd)
  67.            SetWindowText (hWnd, "The title of my window")
  68.        
  69.         case WM_COMMAND
  70.  
  71.             select loword(wParam)                            
  72.             case ID_HELP_ABOUT                
  73.                sys lpdt
  74.                dyn::init(lpdt) '1024
  75.  
  76.                dyn::Dialog( 4,  0, 0, 239, 66, "My About Box", lpdt,
  77.                        DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU or DS_SETFONT,
  78.                        8, "MS Sans Serif" )
  79.                dyn::DEFPUSHBUTTON   "OK", IDOK, 174, 18, 50, 14, 0, WS_EX_LEFT
  80.                dyn::PUSHBUTTON      "Cancel", IDCANCEL, 174, 35, 50, 14, 0, WS_EX_LEFT
  81.                dyn::GROUPBOX        "About this program...", IDC_STATIC, 7, 7, 225, 52, 0, WS_EX_LEFT
  82.                dyn::CTEXT           "An example program showing how to use" cr "Dialog Boxes" cr+cr  "by theForger", IDC_STATIC, 16, 18, 144, 33, SS_CENTER, WS_EX_LEFT
  83.  
  84.                dyn::CreateModalDialog( hWnd, @DialogProc, 0, lpdt )
  85.                
  86.             case ID_FILE_EXIT                
  87.                SendMessage(hWnd, WM_CLOSE,0,0)              
  88.             end select
  89.        
  90.         case WM_CLOSE
  91.             DestroyWindow(hwnd)
  92.        
  93.         case WM_DESTROY
  94.             PostQuitMessage(0)
  95.        
  96.         case else
  97.             return DefWindowProc(hwnd, Message, wParam, lParam)
  98.    
  99.     end select
  100.    
  101.     return 0
  102. end function
  103.  
  104.  
  105. ==================================
  106.  
  107. sub initMenu(sys hWnd)
  108.    sys hMenu
  109.    
  110.    dyn::MENU(hMenu)
  111.    dyn::POPUP "&File"
  112.    dyn::BEGIN
  113.        dyn::MENUITEM "E&xit", ID_FILE_EXIT
  114.    dyn::ENDMenu
  115.    dyn::POPUP "&Help"
  116.    dyn::BEGIN
  117.        dyn::MENUITEM "&About...", ID_HELP_ABOUT
  118.    dyn::ENDMenu
  119.  
  120.    if SetMenu( hWnd, hMenu ) = 0 then
  121.      mbox "SetMenu hMenu failed!"
  122.    end if
  123. end sub
  124.  
« Last Edit: March 24, 2018, 02:51:22 PM by Arnold »