Delphi Complete Fashion Manual Coolbar - Realizing Coolbar New Features Chevron

zhaozj2021-02-11  207

Delphi Complete Fashion Manual Coolbar - Realizing Coolbar New Features Chevron

We found that after IE 5.0, IE has a new feature: When the IE window is reduced, the button on the toolbar cannot be fully displayed, a small button appears on the right side of the toolbar (M $ calls it Chevron, actual This is the new characteristics of Coolbar), and then a drop-down list is displayed, and the hidden button is displayed. This greatly facilitates our use of toolbar.

Then how do we make this characteristic of Delphi's TCOOLBAR control? After I have an overnight consultation information (MSDN), "Solid study" (ah, who throws me eggs ...), finally made it! Good things don't dare to swallow, and share it with you. Let's talk about how to implement it. (The following code is done in Delphi 6)

Step 1: Transform Delphi's TCOOLBAND class

It is recommended to back up the comCtrls.PAS file before doing this step. If you add the RBBS_USECHEVRON this value in a BAND in Coolbar, it will display a drop-down button when the width of this BAN is less than a given value, it will display a drop-down button (Chevron). Below to change the file of COMCTRLS.PAS to implement this feature.

Add two properties (Property) in the Published section of Tcoolband:

// modified by joe huang

Property DealWidth: Integer Read FdealWidth Write SetdealWidth; {Used to tell Band When the width of the BAN is smaller than how much is less than how much is less than how much is less than how much is less than how much is less than how much is less than how much is less than how much is smaller button (Chevron)}

Property Usechevron: Boolean Read Fusechevron Write setusechevron; {Used to determine if the band uses this feature}

// end

The writing methods of the two attributes are as follows:

Procedure Tcoolband.Setusechevron (Const Value: Boolean);

Begin

Fusechevron: = Value;

Coolbar.Updatebands;

END;

Procedure Tcoolband.SetdealWidth (Const Value: Integer);

Begin

FDEALWIDTH: = VALUE;

Coolbar.Updatebands;

END;

Complete to TCOOLBAND, but there is a point to remind, although these two properties are in the Publish section, but they can't see in the design period (I don't know how to do). So we can only access them during run.

Step 2: Transform Delphi TCOOLBAR control

In Comctrs.PAS, find the TCOOLBAR.UPDATEITEM method, first add a constant for this method as follows:

// modified by joe huang

RBBS_USECHEVRON = $ 00000200;

// end

Then find this line in this method (the first time fmask: = place):

Fmas: = rbbim_style or rbbim_colors or rbbim_size or rbbim_background or rbbim_image or rbbim_id;

Add the following code under this line:

// modified by joe huang

IF (getcomctlversion> = comctlversionie5) and Band.usechevron kiln {This function is only after IE5} begin

FStyle: = fStyle or RBBS_USECHEVRON;

IF Band.dealwidth> 0 THEN

Begin

Fmask: = fmask or rbbim_idealsize;

CXIDEAL: = Band.dealwidth;

END;

END;

// end

OK! TCOOLBAR transformation is completed. Generate .dcu file for Comctrls.Pas, method: Copy the comCtrls.pas file to an existing project, add it to this project, compile this project, get it .dcu file, will be .dcu File coverage (note backup) Delphi original, in the Delphi6 / Lib directory.

Step 3: Distinguished in a project.

Open Delphi6, create a new project, put into Coolbar1 on Form1, then add Toolbar1 on Coolbar1, and Coolbar1 will automatically generate a band. Set the AutoSize of Toolbar1 to true, wrapable is false and put your button on it. Set up autosize for Coolbar1 for true, showtext to false (Note: To provide me with a way to locate the band.Text property. There are multiple Bands on Coolbar1. You also You can use your own positioning method.), Setting the text of the band with Toolbar1 is MyToolband. The following starts writing code.

Add a CommCtrl unit after the USES of the Form1 unit; write two custom methods in the Implementation section:

{The total width used to get all the visible buttons on Toolbar1.

Used to assign a value DEALWIDTH that we will add to TCOOLBAND in front of us.

That is, the drop-down button is displayed when the width of the BAN is smaller than the total width of all buttons. }

Function GetTBButtonswidth (Atoolbar: Ttoolbar): cardinal

VAR

Arect, ButtonRect: TRECT;

Tbcount, i: integer;

Begin

All: = RECT (0, 0, 0, 0);

TBCount: = atoolbar.perform (tb_buttoncount, 0, 0);

For i: = 0 to TBCount - 1 DO

Begin

AtoolBar.Perform (TB_GETITEMRECT, I, INTEGER (@ButtonRect));

Allt .right: = all.right (ButtonRect.right - ButtonRect.Left);

END;

Result: = ABS (all);

END;

{Used to position Band

Parameters Bandtext gives you what you want to locate the Text property}

Function getCoolband (BandText: String; ACOOLBAR: TCOOLBAR): Integer;

VAR

I: integer;

Begin

RESULT: = -1;

For i: = 0 to acoolbar.bands.count - 1 dobegin

If AcoolBar.Bands.Items [i] .text = BandText Then

Begin

Result: = i;

Break;

END;

END;

END;

Since Coolbar1 can change the position (when there are multiple BANs), we need a variable to store the current location of Toolbar1's Band (later how to capture the location of the Band).

Define a variable in the Private section:

Private CoolBandIndex: Integer;

Add the following code in Form1:

CoolBandIndex: = getCoolband ('MyToolband', Coolbar1); {Location Band Location}

Coolbar1.Bands.Items [CoolBandIndex] .usechevron: = true; {{自己 加 属 属}

Coolbar1.bands.items [CoolbandIndex] .dealWidth: = GetTbButtonswidth (Toolbar1); {{自己 加 属 属}

Now everyone can run the program, then zoom Form1 to cover the top of the Toolbar1, see the drop button (chevron) is not coming! (What? No! Hurry check out if the front step is correct)

Everyone may notice a question: The button on Toolbar1 may be covered, the other half is also displayed outside, can you make a button once partially shade, the entire button does not display? I found that there is a property hideclippedbuttons in the Toolbar in delphi7, just doing this, this property is only played under ME, 2000, XP, but Delphi6 does not have this property. If you are interested, you can refer to Delphi7, it is easy.

Everyone pays attention, the weight is played. How do I click on this drop-down button (Chevron) to display the smuggled button? And how can we notify us when the BAND changes? The answer is the news! When we click on the drop-down button (Chevron), Coolbar sends a RBN_CHEVRONPUSHED message to its parent window; when changing the position of the BAND, the RBN_LAYOUTCHANGED message will be sent. In fact, these two messages are attached to the WM_NOTIFY message. Below we will intercept these two messages in the Form1 window (generally Form1 is the father of Coolbar1, if you put Coolbar1 in other container controls, you should intercept, the same principle is the same in the corresponding window function). Define two variables and a process in the private section:

Private

FclientInstance: TfarProc;

FPREVCLIENTPROC: TFARPROC;

Procedure NewWindowProc (Var Message: TMessage);

Add code in the Form1's onshow event before implementing the NewWindowProc process (this code is written in front of all code in onshow):

Procedure TFORM1.FORMSHOW (Sender: TOBJECT);

Begin

{$ WARNINGS OFF} fclientInstance: = makeObjectInstance (NewWindowProc);

FPREVCLIENTPROC: = Pointer (getwindowl (gwndowl (gwl_wndproc));

Setwindowlong (Form1.Handle, GWL_WndProc, longint (fclientInstance)); {replacing Form1 window function}

{Warnings on}

{...}

END;

Place a PopupMenu1 on Form1, set its alignment as Paright. Used to show the shaded button.

The implementation of the window function NewWindowProc is as follows:

Procedure TFORM1.NEWWINDOWPROC (VAR Message: TMESSAGE);

Type

{Package a TNMRebarchevron structure. This structure is sent with RBN_CHEVRONPUSHED messages. }

Pnmrebarchevron = ^ TNMRebarchevron;

TNMRebarchevron = Record

HDR: TNMHDR;

Uband: uint;

WID: UINT;

Lparam: lparam;

RC: TRECT;

Lparamnm: lparam;

END;

Const

RBN_CHEVRONPUSHED = RBN_FIRST - 10; VAR

ANMHDR: PNMHDR;

ANMREBARCHEVRON: PNMRebarchevron;

ScreenRect: TRECT;

FirstClipButton, i: integer;

Amenuitem: TMenuItem

{This function is used to get the location (index) of the leftmost left in Toolbar1. }

Function GetFirstClipButton (ACOOLBAR: TCOOLBAR; Atoolbar: Ttoolbar): Integer;

VAR

ButtonRect: TRECT;

TBCount, I, TempWidth: Integer;

Begin

RESULT: = -1;

TempWidth: = 0;

TBCount: = atoolbar.perform (tb_buttoncount, 0, 0);

For i: = 0 to TBCount - 1 DO

Begin

AtoolBar.Perform (TB_GETITEMRECT, I, INTEGER (@ButtonRect));

TempWidth: = TempWidth (ButtonRect.right - ButtonRect.Left);

IF Tempwidth> AtoolBar.width Then

Begin

Result: = i;

Break;

END;

END;

END;

Begin

WITH MESSAGE DO

Begin

IF msg = WM_Notify THEN

Begin

ANMHDR: = PNMHDR (LPARAM);

If Anmhdr.code = RBN_CHEVRONPUSHED THEN {We click the drop-down button (Chevron)}

Begin

Anmrebarchevron: = pnmrebarchevron (lparam);

ScreenRect: = Rect (Clienttoscreen (ANMREBARCHEVRON.RC.TOPLEFT), ClientToscreen (ANMREBARCHEVRON.RC.BOTTOTOMRIGHT);

Firstclipbutton: = getFirstClipButton (Coolbar1, Toolbar1); {Get the leftmost of the left side of Toolbar1 on the left side of the left one of the} if firstclipbutton = -1

PopupMenu1.items.clear; {All menuitem} on PopupMenu1

PopupMenu1.Images: = Toolbar1.images;

For i: = firstclipbutton to Toolbar1.buttoncount - 1 DO {Show all covered buttons on popupmenu1 to display a menuitem}

Begin

Amenuitem: = TMenuItem.create (Self);

IF (Toolbar1.Buttons [i] .style = tbsseparator) or (Toolbar1.Buttons [i] .style = TBSDIVIDER) THEN

Amenuitem.caption: = '-'

Else Begin

Amenuitem.caption: = Toolbar1.Buttons [i] .caption;

Amenuitem.ImageIndex: = Toolbar1.Buttons [i] .imageindex;

Amenuitem.enabled: = Toolbar1.buttons [i] .enabled;

Amenuitem.onclick: = Toolbar1.Buttons [i] .onclick;

if Toolbar1.Buttons [i] .Artion <> nil dam

Amenuitem.Action: = Toolbar1.Buttons [i] .act;

END;

PopupMenu1.Items.Add (amenuitem);

END;

PopupMenu1.Popup (ScreenRect.Right 3, ScreenRect.bottom 3);

END ELSE IF ANMHDR.CODE = RBN_LAYOUTCHANGED THEN {Intercept Band Location Change Message}

Begin

For i: = 0 to coolbar1.bands.count - 1 do

Begin

if Coolbar1.Bands.Items [i] .text = 'MyToolband' Then

Begin

CoolBandIndex: = i;

Break;

END;

END;

END;

END;

Result: = CallWindowProc (FPREVCLIENTPROC,

Form1.handle,

MSG,

WPARAM,

lparam;

END;

END;

At this point, the basic code has been completed (running to see the effect, such coolbar is a little Cool look)!

The above code does not fully apply the actual needs, there are two points to pay special attention:

We see the above code is only assigned to DEALWIDTH in the form1.onshow event: coolbar1.bands.Items [CoolBANDEX] .dealwidth: = GetTbButtonswidth (Toolbar1); When we run Toolbar1 by the big button (or Conversely, then DEALWIDTH's value will be inserted with all buttons on Toolbar1, so that the drop-down button (chevron) cannot correctly appear in it. Therefore, as long as the action changes the total width of all buttons of Toolbar1, it is necessary to re-value the DEALWIDTH. When it is displayed on Toolbar1 to display PopupMenu1 to display different states of these buttons, such as a button for a TBSCHECK button, or a TBSDropDown button (with drop-down menu) how to handle it. In the case of these situations, you can see how other famous shared software is implemented, such as ACDSEE5, Winzip, etc. The article is written, and I don't know if I write it. If you have any questions, please come to Email and I discuss, or ask me to Demo. My email: happyjoe@21cn.com

转载请注明原文地址:https://www.9cbs.com/read-4404.html

New Post(0)