Solved

Accelerated characters with Canvas.Textout()???

Posted on 2004-10-17
12
400 Views
Last Modified: 2013-12-03
I'm making my own buttoncomponent, derived from TCustomControl. Now I want to be able to create a shortcut for the button, using accelerated characters (underlined characters, the ones with an & in front of them in the Caption). How would I do that? And how do I connect a shortcut to the button once I can display the accelerated characters??

I'm using Canvas.TextOut() to display the caption on the button. Tried using a TCustomLabel on top of the button, but there are problems with mousecapture and stuff with that solution, so if itäs possible to use Canvas.TextOut() I'd prefer that...

0
Comment
Question by:mmmMange
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +3
12 Comments
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 12332151
Play around with DT_NOPREFIX in the DrawText function.
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12332184
if your component is named CustomControlXP:

declare in the class definition:
      procedure      Paint; override;

//........

implementation

procedure   TCustomControlXP.Paint;
var
  L:        Word;
  T:        Word;
  H:        Word;
  W:        Word;
begin
  Canvas.Font := Font;
  H := Canvas.TextHeight(Caption);
  W := Canvas.TextWidth(Caption);
  L := (Width - W) div 2;
  T := (Height - H) div 2;
  Canvas.TextOut(L, T, Caption);
end;
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12332203
excuse me, I forgot a row into the procedure:

  Canvas.Brush.Color := Color;
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Expert Comment

by:esoftbg
ID: 12332261
procedure   TCustomControlXP.Paint;
var
  L:        Word;
  T:        Word;
  H:        Word;
  W:        Word;
begin
  Canvas.Font := Font;
  Canvas.Brush.Color := Color;
  H := Canvas.TextHeight(Caption);
  W := Canvas.TextWidth(Caption);
  L := (Width - W) div 2;
  T := (Height - H) div 2;
  Canvas.TextOut(L, T, Caption);
end;
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12332286
procedure   TCustomControlXP.Paint;
var
  L:        Word;
  T:        Word;
  H:        Word;
  W:        Word;
begin
  inherited;
  Canvas.Font := Font;
  Canvas.Brush.Color := Color;
  H := Canvas.TextHeight(Caption);
  W := Canvas.TextWidth(Caption);
  L := (Width - W) div 2;
  T := (Height - H) div 2;
  Canvas.TextOut(L, T, Caption);
end;
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 12334861
It was problem to figure out the position on the X axis, so I used hardcoded numbers in this example. It is not very pretty code, but here is the idea...


procedure TForm1.PaintCaption(S: String);
var
  FirstPart     : String;  // text before the &
  UnderLined    : String;  // underlined character
  LastPart      : String;  // last part - no underline
  lc_pos        : Integer;
begin
  lc_pos      := Pos('&', S);
  FirstPart   := Copy(S, 1, lc_pos - 1);
  UnderLined  := Copy(S, lc_pos + 1, 1);
  LastPart    := Copy(S, lc_pos + 2, length(S) - lc_pos + 2);
  with Self.Canvas do
    begin
      // set color and remove underline (if set)
      Font.Color := clBlack;
      Font.Style := Font.Style - [fsUnderline];
      // output text
      TextOut(2, 2, FirstPart);
      // set underline

      // THIS LINE HERE SHOULD BE EXECUTED IF ALT IS PRESSED
      // ***************************************************
      Font.Style := Font.Style + [fsUnderline];
      // ***************************************************

      // underlined symbol
      TextOut(30, 2, UnderLined);
      // remove underline
      Font.Style := Font.Style - [fsUnderline];
      TextOut(42, 2, LastPart);
    end;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  PaintCaption('Hello &World!');
end;
0
 

Author Comment

by:mmmMange
ID: 12334874
Thanks DragonSLayer, I would never have found that method if you hadn't told me! But there are still problems - the font looks like FixedSys or Terminal, no matter what I set Canvas.Font to.... Weird.

Do you know how I can "connect" a shortcut to my key too?
0
 
LVL 3

Expert Comment

by:jpedef
ID: 12336266
Why you just don't use windows DrawText function.

procedure DrawCaption;
var
  R: TRect;
  s: string;
begin
  R.Left := 50;
  R.Right := 200;
  R.Top := 50;
  R.Bottom := 100;
  s := '&This is a line';
  DrawText(Canvas.Handle, PChar(s), Length(s), R, DT_VCENTER or DT_SINGLELINE or DT_CENTER);
end;

For shortcuts, take a look at TCustomLabel-component's source.
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 12336315
Delphi's TButton uses the CM_DIALOGCHAR message to capture the keystrokes and 'connect' the accelerator character to the button.

To change the font... well, does your component store its own Font values? If it does, then before drawing you would need to do a

Canvas.Font := Font;

or Canvas.Font.Assign(Font);

Or, you can manually select the font... e.g.

var
  FontHandle: HFont;

...

  FontHandle := CreateFont(0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, PChar('Tahoma'));
  SelectObject(Canvas.Handle, FontHandle);

...

0
 

Author Comment

by:mmmMange
ID: 12337086
I can't find any info on CM_DIALOGCHAR in my helpfiles, is there some webpage that describes the message so I know what to do with it? (Tried Google'ing with no result)

About the font - problem solved. I thought I needed to do a GetDeviceContext(Canvas.Handle), but the Canvas.Handle is in fact already a device-context... So now the font works fine.
0
 
LVL 14

Assisted Solution

by:DragonSlayer
DragonSlayer earned 300 total points
ID: 12337331
Are you sure you did a google search? My first search revealed this:
http://www.undu.com/DN970601/00000021.htm
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 200 total points
ID: 12348057
hello mmmMange ,  the TControl and it's decendents will automaticllay put an "Accelerated Charater" in a Control's Caption in to the accelerated charater list for the form. . .(to have an accelerated Charater you place a  &  infront of it when you assign the caption). . .

to get the accerated charater notify you get the delphi generated CM_DIALOGCHAR message and then test for the CharCode with the IsAccel function,
so you do not need any code to initialize an Accerated Character, TControl does that, but you will need to process the CM_DIALOGCHAR message


  private
  { Private declarations }
    procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;


procedure TTextBubble.CMDialogChar(var Message: TCMDialogChar);
begin
with Message do
  if IsAccel(CharCode, Caption) and Enabled and Visible and // also check for enabled and visible
      (Parent <> nil) and Parent.Showing then
    begin
    Click; // I just call this control's OnClick for accelerated charater event
    Result := 1; // have Result of message as one
    end else
    inherited;
end;


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

you seem to already have the text draw, but here is some code I have used -


procedure TTextBubble.Paint;
var
cRect: TRect;
ColorO: TColor;
begin
inherited;
cRect := ClientRect;
if Height > 46 then
cRect.Bottom := cRect.Bottom- 10
else
cRect.Bottom := cRect.Bottom- 4;
with Canvas do
  begin
  ColorO := Brush.Color;
  if FDown then
    Brush.Color := $E0FFF8
    else
    Brush.Color := FColor;
  FillRect(GetClientRect);
  if Length(Caption) > 0 then
  DrawText(Handle, PChar(Caption), -1, cRect, DT_CENTER or DT_SINGLELINE or DT_VCENTER);
  Brush.Color := ColorO;
  end;
end;

 - - - - - - - - - - - - - -  -- - - - - - -  - - -
this may be helpful to you
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Suggested Courses
Course of the Month3 days, 21 hours left to enroll

630 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question