NO

Author Topic: Generic functions for creating rebar and toolbar controls  (Read 795 times)

Offline CFred

  • Member
  • *
  • Posts: 36
Generic functions for creating rebar and toolbar controls
« on: July 30, 2023, 04:27:52 PM »
Introduction
The attached zip file contains generic functions for building rebar and toolbar controls to make the development of programs easier.

It allows normal buttons, dropdown buttons and grouped buttons to be added to a toolbar as well as controls such as an edit box or combobox. The images for the toolbar buttons need to be included in a resource file.

The toolbar may be included in a rebar control that can be set up using the functions in the zipped file, or it may be used in a window on its own.

The file, main.c, demonstrates how to use these functions

Including the functions in your project
Any project that uses these functions must incorporate the instruction:

Code: [Select]
#include "ToolbarRebarFunctions.h"
into a file in the project to make these functions available.

The three files: ToolbarMacros.h, ToolbarRebarFunctions.c and ToolbarRebarFunctions.h need to be included in any project that uses these functions.

Building a toolbar
1. Create a toolbar control
To create a toolbar control and obtain a handle for it call the function BuildToolbar() defined as:

Code: [Select]
HWND BuildToolbar(HWND hparent, int ToolbarID)
This requires two parameters:

hparent - the handle of the window in which the toolbar will be put.
ToolbarID -  a command identifier for the toolbar.

It returns the handle of the toolbar if it is created successfully or NULL if the toolbar cannot be created

2. Adding a button to the toolbar
Bitmapped images for the toolbar buttons must be included in a resource file
To add a button to the toolbar call the function AddButtonToToolbar() defined as:

Code: [Select]
void AddButtonToToolbar(HWND hwndToolbar, int bitmapId, enum btnStyle Style, int position)
This requires four parameters:

hwndToolbar - the handle for the toolbar to be used
bitmapId - the command identifier of the button. This is the same identifier that is given to the image of the button in the resource file.
position - the position of the button in the toolbar, starting from 0. A value of -1 inserts the button after any other buttons that have already been inserted in the toolbar
Style - This sets the style of the button. It can be one of the following values:

- Normal for a normal Toolbar button
- Toggle for a toggle toolbar button - this stays pressed in when clicked and pops up when clicked a second time
- Dropdown if the button is to have a separate dropdown arrow. The button and the accompanying drop down arrow will respond differently to each other when clicked
- WholeDropdown for a button that has a combined dropdown arrow and button. Clicking the button will produce the same response as clicking the dropdown arrow.
- Group to put a button in a group. Only one button in the group is shown as pressed in at any one time.

Call this function for each button that is to be added to the toolbar.

3. Adding separators to the toolbar
To add a separator to the toolbar call the function AddSeparatorToToolbar() which is defined as

Code: [Select]
void AddSeparatorToToolbar(HWND hwndToolbar, int SeparatorID)
This requires two parameters:

hwndToolbar - the handle for the toolbar to be used
SeparatorID - a command identifier. Set this to 0 for a normal separator. The purpose of the integer SeparatorID will be explained next.

4. Adding controls to the toolbar
To add a control (combo box or edit box) to the toolbar, space must be reserved for it. Space can be reserved for the control by using a separator that is added to the toolbar using the function AddSeparatorToToolbar() where the second parameter for this function, SeparatorID, must be a non-zero command identifier.

The control to be inserted must be placed over this separator by calling the function InsertControlInToolbar() which is defined as:

Code: [Select]
HWND InsertControlInToolbar(HWND hWndToolbar, WORD ctrlWidth, int IDSeparator, int CtrlType, int IDControl)
This requires six parameters:

hWndToolbar - the handle for the toolbar to be used
ctrlWidth - the width of the control (in pixels) that will be added to the toolbar
IDSeparator - the command identifier of the separator where the control will be placed
CtrlType - set this to 0 to insert an editbox and 1 to insert a combobox
IDControl - A command identifier for the editbox or combobox
*New*
addStyles Extra styles to add to the control, for example, CBS_SORT to sort a combo box

This function returns the handle of the control if it it added successfully, otherwise it returns NULL.

More than one control can be added to the toolbar if required.

5. Responding to clicks on a dropdown button
A WM_NOTIFY message is sent to the callback procedure of the main window when a mouse clicks on a dropdown button. If the dropdown button is to show a menu then the code in the zipped file can help with this using the function ProcessToolbarMsg() defined as:

*Updated*
Code: [Select]
BOOL ProcessToolbarMsg(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, int menuCommands)
This requires five parameters:

hwnd, msg, wParam and lParam are the normal parameters sent to the WM_NOTIFY message

The last parameter, menuCommands, is the identifier of the menu that is to be shown when the dropdown arrow is clicked.

The demonstration program in the zipped file shows how to incorporate this in response to the WM_NOTIFY message and call the function ProcessToolbarMsg().

It is not possible to write a generic function for all possible responses to clicking on a dropdown button eg clicking on the dropdown button may need to show a colour palette, so the programmer will need to write their own function to achieve this. Hopefully the code in the zipped file will give an indication of how this may be achieved.

Building a rebar control and inserting a toolbar in it
1. Creating a rebar control
To create a rebar control and obtain a handle for it call the function MakeRebar() defined as:

Code: [Select]
HWND MakeRebar(HWND hwndParent, int IDRebar)
This requires two parameters:

hwndParent - the handle of the window that will contain the rebar control
IDRebar - an identifier for the rebar control

The function will return the handle of the rebar control if successful, otherwise it will return NULL.

2. Inserting a toolbar into a rebar control
To insert a toolbar in a band of the rebar control call the function InsertToolbarInBand() defined as:

Code: [Select]
BOOL InsertToolbarInBand(HWND hwndRebar, HWND hwndToolbar)
This requires two parameters:

hwndRebar - the handle of the rebar control that is to receive the toolbar
hwndToolbar - the handle of the toolbar control that is to be inserted in the band.

The zip file contains the file 'Main.c' that demonstrates how to use the above functions.
            
Conclusion
There is a shortage of examples on the internet for Windows programming in the C language and consequently it can take a considerable amount of time to put code together from the API information provided by Microsoft (it took me several days just to produce this code for the toolbar and rebar). I hope that the code I have provided in the zipped file will start to address the shortage in basic examples of Windows programming in the C language.

Acknowledgment
With thanks to frankie for resolving a few issues.

With thanks to John Z for providing the instructions as a PDF file. The zip file has been updated to version 2 to include this file.

« Last Edit: August 14, 2023, 12:54:52 PM by CFred »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Generic functions for creating rebar and toolbar controls
« Reply #1 on: July 30, 2023, 04:39:59 PM »
Nice.  :)
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline Kobold

  • Member
  • *
  • Posts: 13
Re: Generic functions for creating rebar and toolbar controls
« Reply #2 on: July 30, 2023, 10:58:25 PM »
That is some readable, commented and documented code.
Well done, excellent work!  8)

Offline John Z

  • Member
  • *
  • Posts: 796
Re: Generic functions for creating rebar and toolbar controls
« Reply #3 on: July 31, 2023, 04:03:33 AM »
Nice contribution CFred!  I've downloaded to try in my next project.


Good Work, Thanks!

John Z

You can find some nice example code at https://www.codeproject.com/  account sometimes required though,
and there are other places if search long enough....

Offline CFred

  • Member
  • *
  • Posts: 36
Re: Generic functions for creating rebar and toolbar controls
« Reply #4 on: July 31, 2023, 12:07:09 PM »
Thanks, John Z.

I joined Code Project many years ago when I first used Pelles C and there seemed to be more C code for Windows available at that time (now there seems to be a lot for C++ and C#). I moved on to using Delphi and then when that compiler became unreasonably expensive I moved on to using Pure Basic which was very easy to use and enabled programmers to access windows API when necessary. However, I decided to move back to Pelles C for a particular project I had in mind, but I find that I am very rusty in its use for Windows. Sadly, I cannot find any Windows code that I posted on this forum in the early years.

I have tried using ChatGPT https://chat.openai.com, with little success. Also I have used the Bing chat bot, with limited success.

Offline John Z

  • Member
  • *
  • Posts: 796
Re: Generic functions for creating rebar and toolbar controls
« Reply #5 on: August 01, 2023, 12:12:05 AM »
HI CFred,

I've created a pdf of your documentation posted at:

https://forum.pellesc.de/index.php?PHPSESSID=kp6kk2c01jubihmpsov1tap13m&topic=10952.msg37981#msg37981

for reference use offline. 

Good documentation is worth preserving. and if you'd like to include it in your zip project file it is yours of course. 

If you'd rather not have the pdf exist I'll delete this post...

John Z
« Last Edit: August 01, 2023, 12:15:29 AM by John Z »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2096
Re: Generic functions for creating rebar and toolbar controls
« Reply #6 on: August 01, 2023, 10:21:13 AM »
To create good professional documentation embedded in the sources I suggest to use Doxygen.
This the most widley used software and is free.  ;)
It is better to be hated for what you are than to be loved for what you are not. - Andre Gide

Offline CFred

  • Member
  • *
  • Posts: 36
Re: Generic functions for creating rebar and toolbar controls
« Reply #7 on: August 01, 2023, 11:37:07 AM »
@John Z: Thank you for providing the instructions in a PDF file. I have updated the zip file in the first post to included these.

@frankie: I will have to look at Doxygen when I get time.

Offline CFred

  • Member
  • *
  • Posts: 36
Re: Generic functions for creating rebar and toolbar controls
« Reply #8 on: August 14, 2023, 12:43:06 PM »
I have made a few improvements to the code for the toolbar:

1. The function InsertControlInToolbar() now takes an additional parameter that allows you to add more styles to the control eg CBS_SORT to sort a combo box

2. ProcessToolbarMsg() has been simplified. It no longer needs a structure to be passed to it, nor the number of buttons being added.

Corresponding changes have been made to the main.c module.

The updates are in the zipped file (RebarToolbar -  v2.1.zip) in the first post of this thread