⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 120665.htm

📁 在天极网上发布的各类delphi原码及技巧文档
💻 HTM
📖 第 1 页 / 共 3 页
字号:
&nbsp;&nbsp;  inherited;<br>&nbsp;&nbsp; FGap := 8; <br>end;<br>  现在我们来看一下Adjust方法,它负责安排LinkedLabel或者关联控件的放置(取决于MoveLabel参数的取值)。正如你将在代码中看到的,LinkedLabel与相关控件的实际位置取决于Gap和OnTop属性(见图2)。虽然我们在OnTop中只提供了两种可能的选择,不过可以很容易的对其编程以提供更多的可能性。不过,把TlinkedLabel武装到牙齿(原文是“add a lot of "bells and whistles"”,译者注)并不是本文的重点,这项任务就委托给读者们来完成吧。<br>procedure TLinkedLabel.Adjust(MoveLabel: Boolean); <br>var<br>&nbsp;&nbsp;dx, dy: Integer; <br>begin<br>&nbsp;&nbsp;  if (Assigned(FAssociate)) then begin<br>&nbsp;&nbsp;&nbsp;&nbsp;  if (FOnTop) then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dx := 0; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dy := Height + FGap; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dx := Width + FGap; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dy := (Height - FAssociate.Height) div 2; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br>&nbsp;&nbsp;&nbsp;&nbsp;  if (MoveLabel) then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Left := FAssociate.Left - dx; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Top&nbsp;&nbsp;:= FAssociate.Top - dy; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br>&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FAssociate.Left := Left + dx; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FAssociate.Top&nbsp;&nbsp;:= Top + dy; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br>&nbsp;&nbsp; end;<br>end;<br>  现在,我们来完成Gap和OnTop属性的set方法(见图3),以便当Gap或者Onop属性被修改时我们可以改变LinkedLabel的位置。<br>procedure TLinkedLabel.SetGap(Value: Integer); <br>begin<br>&nbsp;&nbsp; if (FGap &#60;&#62; Value) then<br>&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FGap := Value; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Adjust(True); <br>&nbsp;&nbsp;&nbsp;&nbsp; end;<br>end;<br>&nbsp;&nbsp;<br>procedure TLinkedLabel.SetOnTop(Value: Boolean); <br>begin<br>&nbsp;&nbsp;  if (FOnTop &#60;&#62; Value) then<br>&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FOnTop := Value; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Adjust(True); <br>&nbsp;&nbsp;&nbsp;&nbsp; end;<br>end;<br><br>现在是SetAssociate方法<br>procedure TLinkedLabel.SetAssociate(Value: TControl); <br>begin<br>&nbsp;&nbsp;  if (Value &#60;&#62; FAssociate) then begin<br>&nbsp;&nbsp;&nbsp;&nbsp;  if (Assigned(FAssociate)) then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FAssociate.WindowProc := FOldWinProc; <br>&nbsp;&nbsp;&nbsp;&nbsp; FAssociate := Value; <br>&nbsp;&nbsp;&nbsp;&nbsp;  if (Assigned(Value)) then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Adjust(True); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enabled := FAssociate.Enabled; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Visible := FAssociate.Visible; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  FOldWinProc := FAssociate.WindowProc; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FAssociate.WindowProc := NewWinProc; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br>&nbsp;&nbsp; end;<br>end;<br><br>  为了便于理解,我们需要详细的讨论一下WindowProc属性。WindowProc被定义为TwndMethod类型。TwndMethod可以在Controls单元中找到,定义如下:<br>TWndMethod = procedure(var Message: TMessage) of object;<br>  注意,FoldWinProc同样被定义为TwndMethod,并且NewWinProc方法拥有与TwndMethod相同的参数结构。这就允许我们将FoldWinProc指向WindowProc的当前值,并把WindowProc重定向到NewWinProc方法。如果WindowProc只是另一个事件属性的话,我们为什么需要使用FoldWinProc呢?因为WindowProc与其它事件属性的不同之处在于WindowProc指向一个已经存在的事件处理器。如果我们只是简单的将WindowProc指向我们的方法,这个控件将不能再对任何Windows消息产生响应。为了解决这个问题,我们在把WindowProc指向NewWinProc之前把FoldWinProc设置为WindowProc的当前值。<br>  在NewWinProc中,我们通过FoldWinProc调用原先的消息处理器(message handler),并且处理特定的Windows消息。因为我们修改了关联控件的WindowProc值,因此要在把关联改变到一个新的控件之前恢复它从前的取值。<br>  避免把关联控件的WindowProc属性指向一个不再存在的例程也同样重要。如同我们所见的,在析构器中调用SetAssociate(nil)将会把WindowProc恢复为初始值。<br>destructor TLinkedLabel.Destroy; <br>begin<br>&nbsp;&nbsp;SetAssociate(nil);<br>&nbsp;&nbsp; inherited;<br>end<br>  另外,我们也不希望关联到一个不再存在控件。通过覆盖Notification方法,我们可以知道关联组件何时被销毁,从而重置关联的指针:<br>procedure TLinkedLabel.Notification(AComponent: TComponent; <br>&nbsp;&nbsp;Operation: TOperation); <br>begin<br>&nbsp;&nbsp;  if ((Operation = opRemove) and<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  (AComponent = FAssociate)) thenSetAssociate(nil);<br>end;<br>  现在我们来看NewProc方法。这里,我们只是寻找发送给关联控件的特定Windows消息。认识到这一点是很重要的:虽然方法通过关联控件调用,但它实际上是LinkedLabel的一部分,例如,Self=LinkedLabel,而不是关联控件。这对为一个按钮创建onclick事件处理器来说也是一样的,onclick事件处理器是作为按钮父窗体的一部分,而不是扩充Tbutton类的新方法。<br>procedure TLinkedLabel.NewWinProc(var Message: TMessage); <br>var<br>&nbsp;&nbsp;Ch: Char; <br>begin<br>&nbsp;&nbsp;  if (Assigned(FAssociate) and (not FUpdating)) then begin<br>&nbsp;&nbsp;&nbsp;&nbsp;  FUpdating := True; <br>&nbsp;&nbsp;&nbsp;&nbsp;  try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  case(Message.Msg) of<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WM_CHAR: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (FCapsLock) then begin<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -