delphi – 在使用Windows API绘制一个按钮时,是否负责绘制标题?
介绍
我已经对Windows API和Parts and States有一点乐趣,看看控件如何可以画在画布上. 有了很多的尝试和错误,我设法得出这个程序,将一个按钮画在画布上: type TButtonState = (bsDefault,bsDisabled,bsHot,bsNormal,bsPressed); procedure DrawButton(ACanvas: TCanvas; X,Y,AWidth,AHeight: Integer; AFont: TFont; Caption: string; ButtonState: TButtonState); var Size: TSize; R: TRect; H: HTHEME; begin Size.cx := AWidth; Size.cy := AHeight; R := Rect(X,X + AWidth,Y + AHeight); if Winapi.uxTheme.UseThemes then begin H := OpenThemeData(0,'BUTTON'); if H <> 0 then try ACanvas.Brush.Style := bsClear; if AFont <> nil then begin ACanvas.Font.Assign(AFont); end; case ButtonState of bsDefault: begin GetThemePartSize(H,ACanvas.Handle,BP_PUSHBUTTON,PBS_DEFAULTED,nil,TS_DRAW,Size); DrawThemeBackground(H,R,nil); end; bsDisabled: begin GetThemePartSize(H,PBS_DISABLED,nil); //ACanvas.Font.Color := $00838383; //todo get actual disabled font color end; bsHot: begin GetThemePartSize(H,PBS_HOT,nil); end; bsNormal: begin GetThemePartSize(H,PBS_NORMAL,nil); end; bsPressed: begin GetThemePartSize(H,PBS_PRESSED,nil); end; end; // draw the button caption DrawText(ACanvas.Handle,PChar(Caption),Length(Caption),DT_CENTER or DT_VCENTER or DT_SINGLELINE); finally CloseThemeData(H); end end else begin // draw button in classic theme? end; end; 如果我这样调用那个程序: procedure TForm1.FormPaint(Sender: TObject); begin DrawButton(Image1.Canvas,10,75,25,Form1.Font,'Normal',bsNormal); DrawButton(Image1.Canvas,40,'Default',bsDefault); DrawButton(Image1.Canvas,70,'Disabled',bsDisabled); DrawButton(Image1.Canvas,100,'Hot',bsHot); DrawButton(Image1.Canvas,130,'Pressed',bsPressed); end; 结果是我的预期是如此,像任何Windows按钮控件一样出现: 题 虽然我正在玩这个程序,但我很快意识到该按钮没有标题,我看不到添加字幕的方式,而不是自己绘制在按钮的顶部.您可以看到,“禁用”按钮仍然显示默认的字体颜色,禁用的控件通常具有不同的颜色,以帮助显示控件被禁用.标准Windows主题下禁用的字体颜色为$00838383(使用屏幕颜色选择器找到),但硬编码值绝对不是一个好主意,因为这些值通常对每个主题都是唯一的. 我的问题有几个部分,当使用Winows API绘制一个按钮时,我们必须自己手动绘制字幕?如果是这样,如何确保我正在绘制正确的字体名称,样式和大小等,以确保按钮与系统绘制的按钮相同? 奖金 当主题未启用时,应如何以经典Windows样式绘制按钮? 解决方法
你应该自己画出文字.您可以使用主题API来绘制文本.例如:
... bsDisabled: begin GetThemePartSize(H,nil); DrawThemeText(H,DT_CENTER or DT_VCENTER or DT_SINGLELINE,R); //ACanvas.Font.Color := $00838383; //todo get actual disabled font color end; ... 由于您可以使用适当的状态调用api,请将该调用包括在分支中,并删除对DrawText的调用. 您可以使用DrawFrameControl作为经典风格.例如: DrawFrameControl(ACanvas.Handle,DFC_BUTTON,DFCS_BUTTONPUSH); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |