• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 486
  • Last Modified:

Accelerated characters with Canvas.Textout()???

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
mmmMange
Asked:
mmmMange
  • 4
  • 3
  • 2
  • +3
2 Solutions
 
DragonSlayerCommented:
Play around with DT_NOPREFIX in the DrawText function.
0
 
esoftbgCommented:
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
 
esoftbgCommented:
excuse me, I forgot a row into the procedure:

  Canvas.Brush.Color := Color;
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
esoftbgCommented:
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
 
esoftbgCommented:
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
 
Ivanov_GCommented:
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
 
mmmMangeAuthor Commented:
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
 
jpedefCommented:
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
 
DragonSlayerCommented:
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
 
mmmMangeAuthor Commented:
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
 
DragonSlayerCommented:
Are you sure you did a google search? My first search revealed this:
http://www.undu.com/DN970601/00000021.htm
0
 
Slick812Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

  • 4
  • 3
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now