• Welcome to Jose's Read Only Forum 2023.
 

toolbar question

Started by Frank Brübach, February 03, 2010, 12:46:33 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frank Brübach

hello all.
I am testing some toolbar examples and made this first style for my project (see picture below).

here are my questions:

a) - it's possible to load Icons separately from own sources (*.bmp, *.png files) ? I am meaning not load from existing 'icon bitmap bar' like for example "toolbar24hot.bmp".

b) - I am using for my example three different bitmaps sources (toolbar24hot.bmp, toolbar24disabled, toolbar24normal) to see how this ImageList (LoadImage) works, but wanted to get new Icons for my buttons in toolbar, so I have to load every Icon new by name, that's correct ? Any powerbasic example exists for this case ?

c) - last not least: I am looking for an mdi example here at the board (I have found example from josé  with "CWindow.inc"). Is there any other example ?

that's all for the moment.

best regards, thanks in advance, frank

Frederick J. Harris

At the Forger's Win32 Tutorial there is an Mdi example that uses Toolbars, but they just load standard Windows Icons.  The tutorial is here...

http://www.winprog.org/tutorial/app_four.html

...and its in C.  Don't know how helpful that would be as PowerBASIC has a few MDI examples in the Samples directory of your installation, but you've probably seen them. 

Frank Brübach

#2
thanks fred for the link, but I am looking for a simple and pure mdi example  ;)
I have tried first steps with "pbnote2" from PBWIN folder some month ago, that was very ok for that job.
But now I would like to use other Icons and toolbar (double toolbar, see picture above!) plus MDI features. Perhaps I can catch and modify some old examples.

I have only managed to make menus but no MDI text editors and MDI client window. perhaps anybody has a link or existing example, I will check and manage to include this stuff into my existing example, I am sure :)

best regards, frank
ps: I add my new 'double toolbar window' exe as zip file

José Roca

 
RE Toolbars: LoadImage only works with bitmaps and icons, so forget about PNGs, JPEGs and the likes. Best way: Use icons and image lists.

RE MDI: A search of this forum returns the following link:
MDIDEMO - Multiple-Document Interface Demonstration
http://www.jose.it-berater.org/smfforum/index.php?topic=31.0


Frederick J. Harris

Might be a problem with that link Jose.  At least from here I'm getting a bad link message.

Frank Brübach


Frank Brübach

#6
thanks josé for the little MDI example. must still adept this one for my purpose.

well, this is a general question, but for me important how to go on into future for creating an own little editor and learning more about window api and sdk window frame. special topic MDI client window.

1) ICON TOOLBAR resource loading where? -> the old "pbnote2" example from powerbasic folder (samples/sdk folder) uses MDI related calls, very fine so far. but where does this powerbasic example gets his ICONS for TOOLBAR from ? what resource does this example use to fetch this little window icons, I have read some weeks ago this is an automatic process, but how does it work ? and it's possible to change these boring (I suggest predefined) TOOLBAR ICONS ? Must laugh a little one, but that's important for me!

2) other way would be to make new window api with new ICONS (via ImageList) for toolbar and I like the way to make a double ICON toolbar gui you can see in my last post. but to add MDI client window for this way it's hard and this will take some days to manage. - I have grasped to build in this little mdi window for my double Icon Toolbar window, but it's not perfect. step by step climbing to the mountain.

Perhaps anybody can give more information about ICON TOOLBAR loading for this "pbnote2" example I have made for my new exercise (AdamEvaBasic Editor, it's only a dummy test example) too.

My wish is to make new layout and button handling for graphic work ( so I prefer second way with double Icon toolbar!), it's just a beginning but it's important to choose the right way. I am thinking you know what I am meaning :)

be curious to get an answer about toolbar Icons ("pbnote2") where they are coming from ;)

nice day, frank

José Roca

Quote
1) ICON TOOLBAR resource loading where? -> the old "pbnote2" example from powerbasic folder (samples/sdk folder) uses MDI related calls, very fine so far. but where does this powerbasic example gets his ICONS for TOOLBAR from ? what resource does this example use to fetch this little window icons,

From commctrl.dll. It uses pre-defined STD_XXX constants that are identifiers for them.

Quote
I have read some weeks ago this is an automatic process, but how does it work ? and it's possible to change these boring (I suggest predefined) TOOLBAR ICONS ? Must laugh a little one, but that's important for me!

Sure. Make a bitmap strip with your icons and use an image list.

Frank Brübach

question about cWindow + toolbar :)

hi josé, perhaps you can give advice. I try to use your cWindow class (MDI example) and thought it's perhaps also possible to make a toolbar and load Icons with "addImage".

   pWindow.AddToolbar(hwnd, %IDToolbar, "&Toolbar", 0, 0, 0, 0, -1, -1)
   pWindow.AddImageLabel(hwnd, %IDImageLabel, "&Static", 0, 0, 0, 0, -1, -1)


do you have made any example with cWindows and *.AddImageLabel ?

I am asking because I like this short way of coding with cWindow!

best regards, franko

José Roca

#9
 
Quote
[...] and thought it's perhaps also possible to make a toolbar and load Icons with "addImage".

No. AddImageLabel is to add an image label. It is equivalent to DDT's CONTROL ADD IMAGE.

A toolbar needs an image list. It is not a caprice of SDK programmers, always wanting to make things the hard way :) . If you want to build the image list at runtime, instead of using a bitmap strip and a resource file, then you can do the following (remember to change the paths and names of the icons with yours):


#COMPILE EXE
#DIM ALL

%USEMACROS = 1                      ' // Use macros
#INCLUDE ONCE "CWindow.inc"         ' // CWindow class
#INCLUDE ONCE "CommCtrl.inc"        ' // Common controls

%IDC_TOOLBAR  = 1001
%IDM_16_FIRST = 100
%IDM_16_LAST  = 101

' ########################################################################################
' Main
' ########################################################################################
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG

  ' // Create an instance of the class
  LOCAL pWindow AS IWindow
  pWindow = CLASS "CWindow"
  IF ISNOTHING(pWindow) THEN EXIT FUNCTION

  ' // Create the main window
  LOCAL hwnd AS DWORD
  hwnd = pWindow.CreateWindow(%NULL, "SDK Window", 0, 0, 500, 350, -1, -1, CODEPTR(WindowProc))

  ' // Add a Toolbar
  LOCAL hToolbar AS DWORD
  hToolbar = pWindow.AddToolBar(hwnd, %IDC_TOOLBAR, "", 0, 0, 500, 28, %WS_CHILD OR %WS_VISIBLE OR %CCS_TOP OR %TBSTYLE_FLAT)

  ' // Create and initialize the image list
  LOCAL hImageList AS DWORD
  hImageList = ImageList_Create(16, 16, %ILC_MASK OR %ILC_COLOR24, 2, 0)
  IF hImageList THEN
     ' // Set the background color to use for drawing images
     ImageList_SetBkColor hImageList, %CLR_NONE
     ' // Add the images to the imagelist (change the paths of the icons if needed)
     LOCAL hImage AS DWORD
     hImage = LoadImage(%NULL, "C:\WINAPI\CWindow\16_FIRST.ico", %IMAGE_ICON, 16, 16, %LR_DEFAULTCOLOR OR %LR_LOADFROMFILE)
     ImageList_ReplaceIcon hImageList, -1, hImage
     DeleteObject hImage
     hImage = LoadImage(%NULL, "C:\WINAPI\CWindow\16_LAST.ico", %IMAGE_ICON, 16, 16, %LR_DEFAULTCOLOR OR %LR_LOADFROMFILE)
     ImageList_ReplaceIcon hImageList, -1, hImage
     DeleteObject hImage
  END IF

  ' // Set the imagelist used with default images
  SendMessage hToolbar, %TB_SETIMAGELIST, 0, hImageList

  ' // Allocate memory for the button info array
  LOCAL pttbb AS TBBUTTON PTR
  pttbb = HeapAlloc(GetProcessHeap(), %HEAP_ZERO_MEMORY, 2 * SIZEOF(TBBUTTON))
  IF pttbb THEN
     ' // Send the TB_BUTTONSTRUCTSIZE message, for backward compatibility
     SendMessage hToolbar, %TB_BUTTONSTRUCTSIZE, SIZEOF(TBBUTTON), 0
     ' // Set the size of the bitmaps
     SendMessage hToolbar, %TB_SETBITMAPSIZE, 0, MAKLNG(16, 16)
     ' // Add buttons to the toolbar
     @pttbb[0].iBitmap   = 0
     @pttbb[0].idCommand = %IDM_16_FIRST
     @pttbb[0].fsState   = %TBSTATE_ENABLED
     @pttbb[0].fsStyle   = %BTNS_BUTTON
     @pttbb[0].dwData    = 0
     @pttbb[0].iString   = -1

     @pttbb[1].iBitmap   = 1
     @pttbb[1].idCommand = %IDM_16_LAST
     @pttbb[1].fsState   = %TBSTATE_ENABLED
     @pttbb[1].fsStyle   = %BTNS_BUTTON
     @pttbb[1].dwData    = 0
     @pttbb[1].iString   = -1
     SendMessage hToolbar, %TB_ADDBUTTONS, 2, pttbb
     ' // Free memory that was allocated for the button info
     HeapFree GetProcessHeap(), 0, pttbb
     ' // Update the size of the toolbar
     SendMessage hToolbar, %TB_AUTOSIZE, 0, 0
  END IF

  ' // Default message pump (you can replace it with your own)
  pWindow.DoEvents

END FUNCTION
' ########################################################################################

' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG

  SELECT CASE uMsg

     CASE %WM_COMMAND
        SELECT CASE LO(WORD, wParam)
           CASE %IDCANCEL
              IF HI(WORD, wParam) = %BN_CLICKED THEN
                 SendMessage hwnd, %WM_CLOSE, 0, 0
                 EXIT FUNCTION
              END IF
        END SELECT

     CASE %WM_DESTROY
        ' // Destroy the image list used by the toolbar
        LOCAL hToolbar AS DWORD
        hToolbar = GetDlgItem(hWnd, %IDC_TOOLBAR)
        ImageList_Destroy SendMessage(hToolbar, %TB_SETIMAGELIST, 0, %NULL)
        ' // Close the main window
        PostQuitMessage 0
        EXIT FUNCTION

  END SELECT

  FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================


Quote
I am asking because I like this short way of coding with cWindow!

I wrote it to ease the use of SDK windows. Sort of DDT for SDK programmers without the limitations of the Windows dialog engine (no MDI with DDT). It simplifies the creation of the main window and controls (even ActiveX controls can be added easily), provides a default message pump and makes very easy to subclass a control.

Before you ask, I don't have plans to add additional classes for each control, and the reason is that it will add a lot of bloat. If I do it, they will be implemented in separate include files and its usage will be optional.


Frank Brübach

#10
thanks josé, your little example helped a lot. I have got it and my little cWindow example looks like cute and a really nice little app with a lot of horrible secrets behind the icon buttons (sic: a joke!). my modified example I add as picture and exe in zip file.

do you think it's smart to use cWindow class for making an editor or it's nearly fussy to do that? otherwise I prefer "pbnote2" sdk example (I have already expand it for my purposes. I will show next weeks, if I am ready). I am thinking it's a similar technique for setting an imagelist for toolbar with icons. I liked the idea with bigger icons and double toolbar (like one of my examples some posts before) and perhaps I will manage that to include a mdi child window for it, don't know. - I am not sure what's the best way. I like cWindow because it's thin and fast and I have a good overview, not coding overkill by more than one or two hundred lines ;)

QuoteIf you want to build the image list at runtime, instead of using a bitmap strip and a resource file, then you can do the following (remember to change the paths and names of the icons with yours):

thanks for showing about this handling with separately loading of different icons! I was exactly looking for this kind of spread variety for making a good and unique toolbar :)

by the way. interesting idea "to ease the use of sdk windows". many thanks!

good evening, thanks, franko

José Roca

 
Quote
do you think it's smart to use cWindow class for making an editor or it's nearly fussy to do that?

CWindow doesn't allow you to do anything more than using pure SDK code. Its main advantage is that you need to write less code. Newbies are scared when they see the Petzold's examples with a lot of lines of code to register the class, find CreateWindowEx cumbersome and don't fully understand message pumps. CWindow allows them to create a main window and add controls as easily as with DDT, yet it is more powerful.

You can also add OCXs (registered or not, licensed or not) in the same way that standard controls and instances of the WebBrowser control that you can use to display HTML code or a web page, or to embed Word documents, .pdf files, Excel spreadsheets or other ActiveX controls like Windows Media Player, Flash movies or anything else supported by Internet Explorer.

It also offers optional High-DPI awareness. Call the SET DPI property passing the DPI used at design time and the window and the controls will be scaled if the user changes the DPI setting of his computer to a different value.

Edwin Knoppert

But it's rather unlikely a 'newbie' will visit your site for alternatives because he got 'scared' about the sdk code.
The new includes will scare them more than the sdk code i guess.
A class as a black box will not help much as well.

We need a poll :)

José Roca

#13
 
I'm providing the source of the class, so it is not a black box.

Anyway, I don't care if they use it or not. It can be useful only to those coding GUIs by hand. The users of visual designers will use what the tool of his choice provides: DDT statements, EZ_ functions, FF_ functions, VD_ dispatch classes...

Users of other compilers seem less scared by my code.

See how this old function:


' ****************************************************************************************
' Creates a licensed instance of a visual control (OCX) and attaches it to a window.
' StrProgID can be the ProgID or the ClsID. If you pass a version dependent ProgID or a ClsID,
' it will work only with this particular version.
' hWndControl is the handle of the window and strLicKey the license key.
' ****************************************************************************************
FUNCTION TB_CreateControlLic (BYVAL strProgID AS STRING, BYVAL hWndControl AS DWORD, BYVAL strLicKey AS STRING) AS LONG

   LOCAL HRESULT AS LONG               ' Result code
   LOCAL ppUnknown AS DWORD            ' IUnknown pointer
   LOCAL ppDispatch AS DWORD           ' IDispatch pointer
   LOCAL ppObj AS DWORD                ' Dispatch interface of the control
   LOCAL ppClassFactory2 AS DWORD      ' IClassFactory2 pointer
   LOCAL ppUnkContainer AS DWORD       ' IUnknown of the container
   LOCAL IID_NULL AS GUID              ' Null GUID
   LOCAL IID_IUnknown AS GUID          ' Iunknown GUID
   LOCAL IID_IDispatch AS GUID         ' IDispatch GUID
   LOCAL IID_IClassFactory2 AS GUID    ' IClassFactory2 GUID
   LOCAL ClassID AS GUID               ' CLSID
   LOCAL pbstrLicKey AS STRING         ' Unicode license key string

   pbstrLicKey = UCODE$(strLicKey)     ' Convert the license key to Unicode

   ' Standard interface GUIDs
   IID_NULL = GUID$("{00000000-0000-0000-0000-000000000000}")
   IID_IUnknown = GUID$("{00000000-0000-0000-c000-000000000046}")
   IID_IDispatch = GUID$("{00020400-0000-0000-c000-000000000046}")
   IID_IClassFactory2 = GUID$("{b196b28f-bab4-101a-b69c-00aa00341d07}")

   ' Exit if strProgID is a null string
   IF strProgID = "" THEN
      FUNCTION = &H80070057 ' %E_INVALIDARG
      EXIT FUNCTION
   END IF

   ' Convert the ProgID to a CLSID
   ClassID = CLSID$(strProgID)

   ' If it fails, see if it is a CLSID
   IF ClassID = IID_NULL THEN ClassID = GUID$(strProgID)

   ' If not a valid ProgID or CLSID return an error
   IF ClassID = IID_NULL THEN
      FUNCTION = &H80070057 ' %E_INVALIDARG
      EXIT FUNCTION
   END IF

   ' Get a reference to the IClassFactory2 interface of the control
   ' Context: &H17 (%CLSCTX_ALL) =
   ' %CLSCTX_INPROC_SERVER OR %CLSCTX_INPROC_HANDLER OR _
   ' %CLSCTX_LOCAL_SERVER OR %CLSCTX_REMOTE_SERVER
   HRESULT = CoGetClassObject(ClassID, &H17, %NULL, IID_IClassFactory2, ppClassFactory2)
   IF ISTRUE HRESULT THEN
      FUNCTION = HRESULT
      EXIT FUNCTION
   END IF

   ' Create a licensed instance of the control
   HRESULT = IClassFactory2_CreateInstanceLic(ppClassFactory2, %NULL, %NULL, IID_IUnknown, STRPTR(pbstrLicKey), ppUnknown)
   ' First release the IClassFactory2 interface
   IUnknown_Release ppClassFactory2
   IF HRESULT <> %S_OK OR ppUnknown = %NULL THEN
      FUNCTION = HRESULT
      EXIT FUNCTION
   END IF

   ' Ask for the dispatch interface of the control
   HRESULT = IUnknown_QueryInterface(ppUnknown, IID_IDispatch, ppDispatch)

   ' If it fails, use the IUnknown of the control, else use IDispatch
   IF HRESULT <> %S_OK OR ppDispatch = %NULL THEN
      ppObj = ppUnknown
   ELSE
      ' Release the IUnknown interface
      IUnknown_Release ppUnknown
      ppObj = ppDispatch
   END IF

   ' Attach the control to the window
   HRESULT = AtlAxAttachControl(ppObj, hWndControl, ppUnkContainer)

   ' Note: Do not release ppObj or your application will GPF when it ends because
   ' ATL will release it when the window that hosts the control is destroyed.

   FUNCTION = HRESULT

END FUNCTION
' ****************************************************************************************


Has been translated to FreeBasic:


' ****************************************************************************************
' Creates a licensed instance of a visual control (OCX) and attaches it to a window.
' StrProgID can be the ProgID or the ClsID. If you pass a version dependent ProgID or a ClsID,
' it will work only with this particular version.
' hWndControl is the handle of the window and strLicKey the license key.
' ****************************************************************************************
FUNCTION AxCreateControlLic (BYVAL strProgID AS LPOLESTR, byval hWndControl AS uinteger, byval strLicKey AS lpwstr) AS LONG
DIM ppUnknown AS lpunknown        ' IUnknown pointer
DIM ppDispatch AS lpdispatch      ' IDispatch pointer
DIM ppObj AS lpvoid               ' Dispatch interface of the control
DIM ppClassFactory2 AS IClassFactory2 ptr  ' IClassFactory2 pointer
DIM ppUnkContainer AS lpunknown   ' IUnknown of the container
'DIM IID_NULL as IID               ' Null GUID
'DIM IID_IUnknown as IID           ' Iunknown GUID
'DIM IID_IDispatch as IID          ' IDispatch GUID
'DIM IID_IClassFactory2 as IID     ' IClassFactory2 GUID
DIM ClassID AS clsid              ' CLSID

' Standard interface GUIDs
'IIDFromString("{00000000-0000-0000-0000-000000000000}",@IID_NULL)
'IIDFromString("{00000000-0000-0000-C000-000000000046}",@IID_IUnknown)
'IIDFromString("{00020400-0000-0000-C000-000000000046}",@IID_IDispatch)
'IIDFromString("{b196b28f-bab4-101a-b69c-00aa00341d07}",@IID_IClassFactory2)
' Exit if strProgID is a null string
IF *strProgID = "" THEN
FUNCTION = E_INVALIDARG
EXIT FUNCTION
END If
' Convert the ProgID in a CLSID
AxScode=CLSIDFromProgID(strProgID,@ClassID)
' If it fails, see if it is a CLSID
IF AxScode<>0 THEN AxScode=IIDFromString(strProgID,@ClassID)
' If not a valid ProgID or CLSID return an error
IF AxScode<>0 THEN    
FUNCTION = E_INVALIDARG
EXIT FUNCTION
END If
' Get a reference to the IClassFactory2 interface of the control
' Context: &H17 (%CLSCTX_ALL) =
' %CLSCTX_INPROC_SERVER OR %CLSCTX_INPROC_HANDLER OR _
' %CLSCTX_LOCAL_SERVER OR %CLSCTX_REMOTE_SERVER    
AxScode = CoGetClassObject(@ClassID,&H17,null,@IID_IClassFactory2,@ppClassFactory2)
IF AxScode<>0 THEN
FUNCTION = AxScode
EXIT FUNCTION
END If
' Create a licensed instance of the control
AxScode=IClassFactory2_CreateInstanceLic(ppClassFactory2,NULL,NULL,@IID_IUnknown,strlickey,@ppUnknown)
DeAllocate(strLicKey)
' First release the IClassFactory2 interface
IClassFactory2_Release(ppClassFactory2)
IF AxScode<>0  OR ppUnknown=0 Then
FUNCTION = AxScode
EXIT FUNCTION
END If
' Ask for the dispatch interface of the control
AxScode = IUnknown_QueryInterface(ppUnknown, @IID_IDispatch, @ppDispatch)
' If it fails, use the IUnknown of the control, else use IDispatch
IF AxScode<>0 OR ppDispatch=0 THEN
ppObj = ppUnknown
Else
' Release the IUnknown interface
IUnknown_Release(ppUnknown)
ppObj = ppDispatch
END If
' Attach the control to the window
AxScode=AtlAxAttachControl(ppObj, hwndcontrol, @ppunkcontainer)
' Note: Do not release ppObj or your application will GPF when it ends because
' ATL will release it when the window that hosts the control is destroyed.
FUNCTION = AxScode
END Function


Patrice Terrier

QuoteAnyway, I don't care if they use it or not. It can be useful only to those coding GUIs by hand. The users of visual designers will use what the tool of his choice provides: DDT statements, EZ_ functions, FF_ functions, VD_ dispatch classes...

Users of other compilers seem less scared by my code.

Coding GUIs by hand is the only way to control everything, thus it seems very logic for a SDK programmer like myself.

But if people need to have their work done fast, then they better look for a true RAD tool or L5G.
Whyle hobbyist programmers could limit themselves to one single tool, professionnal programmers can't, they must have an arsenal at their finger tip and use the best to achieve a specific task. The tools you can use to build a hut, would be totaly inadequate to build a Dubai skyscraper.

José, always provides examples with full source code, and that is the best way to learn from a master, but of course only for those wanting to make the effort to learn and that is the limit of what he can do for you.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com