Author Topic: What is the equivalent for PB IMGBUTTONX ?  (Read 2848 times)

0 Members and 1 Guest are viewing this topic.

chrisc

  • Guest
What is the equivalent for PB IMGBUTTONX ?
« on: March 13, 2018, 02:49:22 PM »
Hello

PB allow us to add an image button,  that is a button with an image on it,  its statement is

CONTROL ADD IMGBUTTONX, hDlg, id&, image$, x, y, xx, yy

see the below image showing the 3 image buttons.  it is a very neat way to display a dialog
hence is there an equivalent image button statement for O2 ?


Charles Pegge

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #1 on: March 13, 2018, 06:11:34 PM »
Chris,

Roland produced an example: examples\WinDynDialogs\OwnerDrawn.o2bas

Control(  "", ID_Button, "BUTTON", BS_OWNERDRAW or WS_DLGFRAME, 35, 20, 20, 20 )

Code: [Select]
'====================================================================
' Owner-draw button demo, modal dialog as main.
'
' Adapted from an example in the Microsoft PSDK
' using bitmaps from: examples\GL\NeHe\data\
'====================================================================

'% review

uses dialogs
'namespace

% DS_CENTER=0x0800
% LR_LOADFROMFILE=0x0010
% IMAGE_BITMAP=0
% ODS_SELECTED=1
% WM_DRAWITEM=0x2B
% SRCCOPY=0xCC0020

type DRAWITEMSTRUCT
  uint  CtlType
  uint  CtlID
  uint  itemID
  uint  itemAction
  uint  itemState
  sys   hwndItem
  sys   hDC
  RECT  rcItem
  dword itemData
end type

! StretchBlt lib "gdi32.dll" (sys hdcDest,int nXOriginDest,nYOriginDest,nWidthDest,nHeightDest,sys hdcSrc,int nXOriginSrc,nYOriginSrc,nWidthSrc,nHeightSrc,dword dwRop) as bool


% ID_Button=100

'====================================================================

function DialogProc( sys hDlg, uint uMsg, sys wParam, lParam ) as int callback

  static sys hBmp1, hBmp2
  static sys hdcMem

  select case uMsg

    case WM_INITDIALOG
       hBmp1 = LoadImage( null, "mask1.bmp" , IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
       if hBmp1 = null then mbox "mask1.bmp missing!"

       hBmp2 = LoadImage( null, "mask2.bmp" , IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
       if hBmp2 = null then mbox "mask2.bmp missing!"

       return true

    case WM_DRAWITEM   
       DRAWITEMSTRUCT lpdis at lParam

       hdcMem = CreateCompatibleDC( lpdis.hDC )

       if (lpdis.itemState and ODS_SELECTED) then
         SelectObject( hdcMem, hBmp2 )
       else
         SelectObject( hdcMem, hBmp1)
       end if

       StretchBlt( lpdis.hDC,
                   lpdis.rcItem.left,
                   lpdis.rcItem.top,
                   lpdis.rcItem.right - lpdis.rcItem.left,
                   lpdis.rcItem.bottom - lpdis.rcItem.top,
                   hdcMem,
                   0,
                   0,
                   128,
                   128,
                   SRCCOPY )

       ' Return hDC member of DRAWITEMSTRUCT to default state.
       ' This is ESSENTIAL for proper button operation.
       DeleteDC( hdcMem )

       return true

    case WM_COMMAND
       if loword(wParam) = IDCANCEL then
         ' This will allow the user to close the
         ' dialog by pressing the Escape key.
         EndDialog( hDlg, null )
       end if

       if hiword(wParam) = BN_CLICKED then
         select case loword(wParam)
           case ID_Button
#ifdef review         
   printl "Click..."
#endif   
         end select

         return true
       end if

    case WM_CLOSE
       DeleteObject( hBmp1 )
       DeleteObject( hBmp2 )

       EndDialog( hDlg, null )

  end select

  return 0
end function

'====================================================================

sys lpdt
dyn::init(lpdt)

Dialog( 1, 0, 0, 100, 75, "Owner Draw Button Demo", lpdt,
        WS_OVERLAPPED or WS_SYSMENU or DS_CENTER )

'Control(  "", ID_Button, "BUTTON", BS_OWNERDRAW or WS_DLGFRAME, 35, 20, 20, 20 )
PushButton( "", ID_Button, 35, 20, 20, 20, BS_OWNERDRAW or WS_DLGFRAME )

CreateModalDialog( 0, @DialogProc, 0, lpdt )

'====================================================================

Arnold

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #2 on: March 15, 2018, 07:20:43 AM »
Hi ChrisC,

your example of IMGBUTTONX is interesting. I do not know much about Powerbasic, I try to achieve the results using WinApi, looking at examples (mostly done with C) and searching in Internet or in the Win32 Help File (which Marc and Mike converted to .chm) which I can get here:
http://www.oxygenbasic.org/reference.html

But I also found the web site of www.garybeene.com with a lot of useful information and his gbsnippets_s. There is small example with ImgButtonX which I tried to rebuild with OxygenBasic. I created a ImgButton.rc file with ResEd. This can also be done with RadAsm of James' O2RadAsm project. It looks like this:

Code: [Select]
#define IDD_DLG1 1000
#define IDC_BTN1 1001

IDD_DLG1 DIALOGEX 10,10,130,130
CAPTION "ImgButton Test"
FONT 8,"MS Sans Serif",0,0,0
STYLE WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU
BEGIN
  CONTROL "IDC_BTN",IDC_BTN1,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP,32,32,65,65
END

Applying these values I used as a pattern SimpleModal.o2bas to create ImgButtonX.o2bas:

Code: [Select]
'http://www.garybeene.com/power/pb-tutor-controls-imgbuttonx.htm

'This short example creates a complete application with a single imgbuttonx control.
'When clicked, the imgbuttonx control responds with a message.
'This tutorial page discusses most of the statements used,
'however the DDT, Controls, Messages, and Callback tutorials provide
'background information that may be helpful in understanding the example.
/*
   #Compile Exe
   #Resource "pb-test.pbr"
   Global hDlg As Dword
   Function PBMain() As Long
      Dialog New Pixels, 0, "ImgButtonX Test",300,300,200,200, _
                                      %WS_SysMenu, 0 To hDlg
      Control Add ImgButtonX, hDlg, 100,"cowgirl", 50,50,100,100
      Dialog Show Modal hDlg Call DlgProc
   End Function

   CallBack Function DlgProc() As Long
      If Cb.Msg = %WM_Command And Cb.Ctl = 100 And _
                        Cb.CtlMsg = %BN_Clicked Then
         MsgBox "Pushed!"
      End If
   End Function 
*/

'====================================================================
' Simple modal dialog as main.
'====================================================================

'% review

uses dialogs
'namespace

% DS_CENTER=0x0800
% LR_LOADFROMFILE=0x0010
% IMAGE_BITMAP=0

! GetDlgItem lib "user32.dll" (sys hDlg, int nIDDlgItem) as sys
! MapDialogRect lib "user32.dll" (sys hDlg, lpRect) as bool
   
#define IDD_DLG1 1000
#define IDC_BTN1 1001

==============================================

'MAIN CODE
=============================================
 
'dim nCmdline as asciiz ptr, hInstance as sys
'&nCmdline = GetCommandLine
'hInstance = GetModuleHandle(NULL)


function DialogProc( sys hDlg, uint uMsg, sys wParam, lParam ) as int callback
  float pixelX, pixelY
 
  sys Button=GetDlgItem(hDlg, IDC_BTN1)
         
  select case uMsg
 
    case WM_INITDIALOG
       RECT rc = {0, 0, 4, 8}
       MapDialogRect (hDlg, @rc)
       PixelX = rc.right/4
       pixelY = rc.bottom/8
         
 
       int width=65*pixelX
       int height =65*pixelY
       hBmp=LoadImage(hDlg,"cowgirl.bmp",IMAGE_BITMAP, width,height, LR_LOADFROMFILE )
       SendMessage (Button, BM_SETIMAGE, IMAGE_BITMAP, hBmp)
 
      return true
 
    case WM_COMMAND
      select case loword(wParam)
        case 1001
           mbox "Pushed!"
           
        case IDCANCEL
           EndDialog( hDlg, null )
      end select
     
    case WM_CLOSE
      EndDialog( hDlg, null )
               
  end select

  return 0
end function

sub winmain()

  sys lpdt
 
  'provide memory for DLGTEMPLATE structure etc   
'  dyn::init(lpdt,nBytes)
  dyn::init(lpdt) '1024

  Dialog( 1,  10,10,130,130, "ImgButton Test", lpdt,
          WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU or DS_CENTER or DS_SETFONT,
          8,"MS Sans Serif" )
  CONTROL "IDC_BTN",IDC_BTN1,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP or BS_BITMAP or WS_DLGFRAME,32,32,65,65

  CreateModalDialog( null, @DialogProc, 0, lpdt )
end sub

winmain()

I used 'LR_LOADFROMFILE' but the image could also be loaded from a linked resource (.res) file.
The info for ImgButtonX states that the size of the image is adapted to the size of the button. This is a bit problematic as dialogs are created using dialog units which are different from screen pixels, so MapDialogRect must be used to convert units to pixels.

I do not know how this is managed with PowerBasic, but my (simple) solution you can see in line 64-67, 70,71 and line 105:
       int width=65*PixelX
       int height =65*PixelY
...
  CONTROL "IDC_BTN",IDC_BTN1,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP or BS_BITMAP or WS_DLGFRAME,32,32,65,65
...
If you change the value 65 to different values in these lines, the size of the image should be displayed correctly. There are certainly other possible ways to resize the image.

Roland

Edit: oops! It seems I have confused width and height. But I corrected this in the meantime.
« Last Edit: March 15, 2018, 08:45:58 AM by Arnold »

chrisc

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #3 on: March 15, 2018, 08:19:49 AM »
Thanxx a lot Roland

The imgbuttonx is a proprietary command by PB.

In PB, they use DDT which is also a set of proprietary commands by PB, i think it is using windows dialog in the backend.
so everything is in Dialog rather than  the normal Windows SDK style. 

to convert from Dialog units to pixels, we again uses a proprietary PB command as shown below

Code: [Select]
Purpose
 Convert dialog units into pixels.
 
Syntax
 DIALOG UNITS hDlg, x&, y& TO PIXELS xx&, yy&
 
Remarks
 The dialog units specified in the x& and y& variables are converted into pixels, based on
the default font of the dialog specified by hDlg. The resultant pixel values are stored in
the xx& and yy& variables.
 

hence it can be tricky to convert from PB directly to O2 as some of the commands are proprietary
the main thing we want to do is to firstly convert all their DDT dialogs to SDK style dialogs
before we convert other things.

we PB programmers are turning to other language is bcos there is no more development of PB
since Bob Zale had passed in 2012

PB is stuck at 32bits, while O2 is already in 64bits that's why more and more PB programmers are joining O2
and that's why there is a demand to convert and translate PB programs to O2


chrisc

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #4 on: March 15, 2018, 09:04:24 AM »
Hello Roland

I have compile your program to become IMGBUTTONX.exe, it is working well, except that it
needs oxygen.dll to be packed with the IMGBUTTONX.exe program.   Why do we need oxygen.dll ?

i asked this question is that i'm new to O2 as i have seen that some exe program that are able to run on its own and
while this program need an oxygen.dll


Arnold

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #5 on: March 15, 2018, 09:54:27 AM »
Hi Chris,

if you want to create an independent executable you can add e.g. these lines at the beginning:

'====================================================================
' Simple modal dialog as main.
'====================================================================
$ filename "ImgButtonX.exe"

use rtl32
'use rtl64

rtl32.inc creates an independent 32-bit exe and rtl64.inc creates a 64-bit exe.

compiling without these lines you will need oxygen.dll (which is 32-bit) to run the binary exe. This can be done by creating the text file oxygen.cfg in the folder of the app which contains a line e.g. like this:
c:\oxygenbasic\oxygen.dll

Roland

Mike Lobanovsky

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #6 on: March 15, 2018, 09:58:58 AM »
Hi Chris,

You can include any and/or all O2 specialized modules as needed per the main objective of your program using the use/uses directives, e.g.:
Code: [Select]
uses Kernel  '1595
uses User    '985
uses Gdi     '945
uses Comctl  '118
uses Comdlg  '28
uses Oleaut  '409
uses Shell   '484
' etc. etc. rtc.

If then you compile your program as an EXE or DLL, you'll get what you want but the resultant executable will be dependent on Oxygen.dll as a run-time library of O2 implementations of BASIC-specific commands and functions.

But there are two special O2 modules that you can also use in your scripts. These are uses rtl32 or uses rtl64. (note you may only use one or the other but not both)

Then the EXE or DLL you compile will incorporate the library of O2 commands and functions in its own file and thus will be 100% stand-alone and independent of Oxygen.dll.

Use uses rtl32 to build 32-bit executables, or uses rtl64, to build them for 64 bits.


[ADD] Oops, Roland was just a tad faster than I! But then, I lost time colorizing.  :D

Arnold

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #7 on: March 15, 2018, 10:42:38 AM »
I forgot to mention that it is also possible to run a program directly without these lines. E.g. after loading a file in Oxide there is the option Compile / Run program directly (F5 or Ctrl-e). Then an oxygen.cfg is not necessary and the program runs in memory using oxygen.dll (32-bit). This is like using the command c:\oxygenbasic\co2.exe <filename>.

With my editor (PSPad) I can achieve this using a macro. I assume this could also be done with O2RadAsm. To develop a program this 'JIT' compiling is much more comfortable than compiling to an exe, running the exe, notice the failure and searching the bug. It will save at least the separate compiling to an exe file and running this exe file over and over again.

By designing OxygenBasic Charles has considered many possible usages.

Roland
 

chrisc

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #8 on: March 15, 2018, 11:37:14 AM »
Thanxx everyone for the knowledge   :)

i hardly use oxide i just use the command prompt to compile which is quite good.

i will       uses rtl64  for all my work from now onwards as i wanted to convert my PB progs to O2 64bits

Charles Pegge

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #9 on: March 15, 2018, 12:31:32 PM »
There is yet another option:

Associate .o2bas files with co2.exe or gxo2.exe. Then you can launch scripts directly from their icons, without using any IDE.

I run my desktop tools this way - no binaries, only o2bas scripts.

Mike Lobanovsky

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #10 on: March 15, 2018, 01:36:51 PM »
 ;D ;D ;D ;D

chrisc

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #11 on: March 15, 2018, 02:36:10 PM »
 :) :)
same here for me Mike !

Karen Zibowski

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #12 on: March 15, 2018, 06:52:00 PM »
Hi Roland

Your coding is cool, and thanks to you

Regards
Karen

Karen Zibowski

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #13 on: March 15, 2018, 06:58:30 PM »
BTW Roland
How do you build that image into a resource, as this is done in PowerBasic
so that the image can be hidden and not modify by the user. 

Can you please show an example how to place the image into a resource and be able to extract it out
as picture button here?

Thanks

Arnold

  • Guest
Re: What is the equivalent for PB IMGBUTTONX ?
« Reply #14 on: March 16, 2018, 07:35:21 AM »
Hi Karen,

sorry for my delayed answer, but there is a problem with my code and I have not yet discovered the reason.

There is a sample in \examples\WinDynDialogs\ExeWithRes which adds an icon and a bitmap as a .res file to an exe. I used the .rc file as a sample for adding oxicon.ico and cowgirl.bmp as images. In ImgButtonX.o2bas I added these lines:

hInstance = GetModuleHandle(NULL)
...
    case WM_INITDIALOG
       sys AppIcon = LoadIcon(hInstance, IDI_APPICON)
       'Set Icon to Main Window
       SendMessage(hDlg, WM_SETICON, ICON_BIG, AppIcon)
...
...

'       hBmp=LoadImage(hDlg,"cowgirl.bmp",IMAGE_BITMAP, width,height, LR_LOADFROMFILE )
       hBmp=LoadImage(hInstance, IDB_BITMAP, IMAGE_BITMAP, width,height, 0 )
       SendMessage (Button, BM_SETIMAGE, IMAGE_BITMAP, hBmp)
...

There is a problem though. The button does not really behave like a pushbutton, although pressing the button or clicking with the mouse works. I do not really understand this. The button should behave the same way as if I used LR_LOADFROMFILE. I tried a workaround:

...
'  CONTROL "IDC_BTN",IDC_BTN1,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP or BS_BITMAP or WS_DLGFRAME,32,32,65,65
  CONTROL "IDC_BTN", IDC_BTN1,"Button",WS_CHILDWINDOW|WS_VISIBLE|WS_TABSTOP or BS_LEFT or BS_PUSHBUTTON or WS_DLGFRAME,32,32,65,65
...

but this does not really look convincing. Maybe someone else could give advice in this case? Perhaps the WinApi function LoadBitmap must be used, but this would change everything. I still think LoadImage should work.

Attached are the files which I used. Perhaps in BuildImgButton.bat and in ImgButtonX.rc the path for OxygenBasic must be adapted.

Roland