我在我的项目中使用此代码:
var
P: TPoint;
MyControl.Perform(WM_LBUTTONDOWN, 0, Longint(PointToSmallPoint(P)));
Run Code Online (Sandbox Code Playgroud)
编译器给了我一个警告:
[Warning]: Unsafe typecast of 'TSmallPoint' to 'Integer'
Run Code Online (Sandbox Code Playgroud)
但是,在Controls.pas 没有任何警告的情况下使用相同的代码- 例如在TControl.BeginDrag方法中:
....
Perform(WM_LBUTTONUP, 0, Longint(PointToSmallPoint(P)));
Run Code Online (Sandbox Code Playgroud)
我看不出有任何{$warnings off}的Controls.pas单元.
为什么编译器会警告我,但会跳过警告Controls.pas?
这段代码不安全吗?
编辑:在我的项目选项 - >编译器消息 - > 选中不安全的类型转换(默认情况下未选中).
也许这就是@David和@Ken无法重现警告的原因.
我试图在Win 7缩放轨道栏中复制PAINT应用程序的行为:(我知道这是一个常见的轨道栏控件)

100%位于市中心.它有11个可用职位:
等等...
12.5%, 25%, 50%, 100%, 200%, 300%, 400%, 500%, 600%, 700%, 800%
所以我的缩放值(ZoomArray)是:
0.125, 0.25, 0.5, 1, 2, 3, 4, 5, 6, 7, 8
这很容易我可以将Min设置为1,Max设置为11并获得我需要的值:
ZoomArray[TrackBar1.Position]
问题是如何保持100%在中心位置,唯一可用的位置是上面的位置?
我试图在数组中使用虚拟值来保持1在中心,例如:
0.125, 0.25, 0.5, -1, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8
并在Change事件上重新定位轨迹栏,但我的逻辑似乎没有正常工作.
有任何想法吗?
我正在尝试模拟TButton的下拉菜单,如下所示:
procedure DropMenuDown(Control: TControl; PopupMenu: TPopupMenu);
var
APoint: TPoint;
begin
APoint := Control.ClientToScreen(Point(0, Control.ClientHeight));
PopupMenu.Popup(APoint.X, APoint.Y);
end;
procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
DropMenuDown(Button1, PopupMenu1);
// ReleaseCapture;
end;
end;
Run Code Online (Sandbox Code Playgroud)
问题是,当菜单被删除时,如果我再次单击该按钮,我希望菜单关闭,但它会再次下降.
我正在寻找专门针对通用Delphi TButton而非任何第三方等效的解决方案.
在C++/C#中,私有类变量的常见约定是m_MyPrivateVar,我相信" m_ "代表"我的"(我可能错了).
在Delphi中,私有类变量以F开头,例如FHandle等.
F意味着什么?富?:)
在我看来TComponent,有一点我想要听取键事件并截取ESC键并在我的组件中处理它,消耗/"吃掉"击键,以便例如所有者表单在那个阶段不会处理它.就像TDragObject你开始时一样拖动并按下取消它ESC.
问题是,TDragObject具有AllocateHWnd由它的拥有者通知的形式CN_KEYDOWN.但是没有人通知我的组件.
我需要WindowProc用自己的表格替换表格吗?如果是,那么如何正确地"按书"做到这一点呢?
只是100%明确:
TMyComponent = class(TComponent)
Run Code Online (Sandbox Code Playgroud)
我做了一个小测试,似乎工作:
TMyComponent = class(TComponent)
private
FOldWindowProc: TWndMethod;
FParentForm: TCustomForm;
procedure FormWindowProc(var Message: TMessage);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
...
constructor TMyComponent.Create(AOwner: TComponent);
begin
if not (AOwner is TWinControl) then
raise Exception.Create('TMyComponent.Create: Owner must be a TWinControl');
inherited Create(AOwner);
// hook parent form
FParentForm := GetParentForm(TWinControl(Owner));
if Assigned(FParentForm) then
begin
FOldWindowProc := FParentForm.WindowProc;
FParentForm.WindowProc …Run Code Online (Sandbox Code Playgroud) 我们的应用程序中有很多表单,我需要一个全局事件处理程序来检测其中一个表单何时被销毁(然后采取一些操作).
ps:我想避免向每个表单添加代码,这些表单需要在主表单即将销毁时向主表单发送消息.此外,大多数表单都是在运行时动态创建和销毁的.
我在考虑使用全球TApplicationEvents.
对此最好的方法是什么?
我想在TGraphicControl上绘制淡出文本,比如Google Chrome上的标签,当没有足够的空间在Canvas上显示整个文本时.
因此,我不想显示省略文本(我知道该怎么做),而是希望它像这样淡出: 
TGraphicControl需要具有透明选项,如TCustomLabel(ControlStyle - [csOpaque]).
这对GDIPlus来说可能是一件容易的事,但我需要使用纯GDI.
我也尝试研究TGradText v.1.0(直接下载)的代码,它几乎完全符合我的需要 - 它可以绘制透明文本,但结果看起来非常糟糕而且不顺畅.我猜是因为它为这个任务制作了一个pmCopy掩码.
这是我根据Andreas Rejbrand的回答编写的代码.我在TImage上使用了PaintBox并预渲染了背景:
type
TParentControl = class(TWinControl);
{ This procedure is copied from RxLibrary VCLUtils }
procedure CopyParentImage(Control: TControl; Dest: TCanvas);
var
I, Count, X, Y, SaveIndex: Integer;
DC: HDC;
R, SelfR, CtlR: TRect;
begin
if (Control = nil) or (Control.Parent = nil) then Exit;
Count := Control.Parent.ControlCount;
DC := Dest.Handle;
with Control.Parent do ControlState := ControlState + [csPaintCopy];
try
with Control do
begin …Run Code Online (Sandbox Code Playgroud) 创建TMenuItem运行时时,如下所示:
mi := TMenuItem.Create([owner]);
并添加到TPopupMenu,如下所示:
PopupMenu1.Items.Add(mi);
我是否需要指定[owner]为PopupMenu1或我可以使用nil?
mi在这种情况下PopupMenu1 将免费,如果是,我该如何验证呢?
我有一种情况,我有一个,TImage并在TPanel其上部分覆盖它,他们共享同一个父母:
------------------
| Image1 |
| ------------ |
| | Panel1 | |
| ------------ |
| |
------------------
Run Code Online (Sandbox Code Playgroud)
Panel1正在接收鼠标按下/移动/向上事件并对其进行处理(Image1也是如此),但在某些情况下,我想将鼠标按下"重定向"到Image1,就像模拟单击Image1而不是Panel1一样.
这是我做的:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (ssLeft in Shift) then
Beep;
end;
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
//...
end;
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('boo!');
end;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
P: TPoint; …Run Code Online (Sandbox Code Playgroud) 我正在使用TADODataSet(D7).
我没有使用我的DataSet在设计模式下创建持久字段.
dsItems.CommandText := 'select ID, ItemName, UserIDCreate from Items';
dsUsers.CommandText := 'select ID, LoginName from Users'; // lookup dataset
Run Code Online (Sandbox Code Playgroud)
如果我双击dsItems并"添加所有文件",然后单击"新建文件"并定义我的查找字段,一切正常.结果dsItems应包含:ID, ItemName, UserIDCreate, LoginName_Lookup
如何在设计时避免完成所有这些操作,并在打开DataSet之后(或不确定)之前添加查找字段.
换句话说:如何模拟"添加所有文件"然后"新建文件"以在运行时添加查找文件?
注意:
从IDE运行John的代码时出现异常.尝试打开DataSet时发生异常:EOleException with message 'An unknown error has occured'.
function TCustomADODataSet.LocateRecord (ADODB.pas) 排队 if FieldCount = 1 then FLookupCursor.Find...
我接受答案,因为已编译的程序正在运行.
如果有人在IDE中运行表单时可以验证是否获得异常,那将是很好的.