如何自定义dbnavigator(customize the dbnavigator)

“好的,DBNavigator负责导航数据和管理记录。不幸的是,我的客户想要更多用户友好的体验,如自定义按钮图形和标题,…”...

“好的,DBNavigator负责导航数据和管理记录。不幸的是,我的客户想要更多用户友好的体验,如自定义按钮图形和标题,…”

Vector speech bubble icons

此查询来自一位正在寻找增强DBNavigator组件功能的方法的Delphi开发人员。

DBNavigator是一个很好的组件,它提供了一个类似VCR的界面,用于在数据库应用程序中导航数据和管理记录。记录导航由第一个、下一个、上一个和最后一个按钮提供。记录管理由编辑、发布、取消、删除、插入和刷新按钮提供。在一个组件中,Delphi提供了对数据进行操作所需的一切。

然而,正如电子邮件查询的作者所说,DBNavigator缺少一些特性,如自定义图示符、按钮标题等。

更强大的dbnavigator

许多Delphi组件都具有对Delphi开发人员标记为不可见(“受保护”)的有用属性和方法。希望可以使用一种称为“受保护黑客”的简单技术来访问组件的受保护成员。

首先,将为每个DBNavigator按钮添加标题,然后添加自定义图形,最后,将在OnMouseUp上启用每个按钮。

从“无聊”DBNavigator到以下任一选项:

  • 标准图形和自定义标题
  • 只有字幕
  • 自定义图形和自定义标题

让我们摇滚吧

DBNavigator具有受保护的按钮属性。这个成员是TNavButton的数组,TSpeedButton的后代。

由于此受保护属性中的每个按钮都继承自TSpeedButton,如果您得到我们的帮助,您将能够使用“标准”TSpeedButton属性,如:标题(向用户标识控件的字符串)、字形(显示在按钮上的位图)、布局(确定图像或文本显示在按钮上的位置)。。。

从DBCtrls单元(定义了DBNavigator)可以“读取”受保护按钮属性声明为:

Buttons: array[TNavigateBtn] of TNavButton;

其中TNavButton继承自TSpeedButton,TNavigateBtn是一个枚举,定义如下:

TNavigateBtn = (nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete, nbEdit, nbPost, nbCancel, nbRefresh);

请注意,TNavigateBtn包含10个值,每个值标识TDBNavigator对象上的不同按钮。现在,让我们看看如何破解DBNavigator:

增强型dbnavigator​

首先,通过放置至少一个DBNavigator、一个DBGrid、一个DataSoure和一个您选择的Dataset对象(ADO、BDE、dbExpres等),设置一个简单的数据编辑Delphi表单。确保所有组件都已“连接”。

其次,通过在表单声明上方定义一个继承的“虚拟”类来攻击DBNavigator,如:

type THackDBNavigator = class(TDBNavigator); type TForm1 = class(TForm) ...

接下来,为了能够在每个DBNavigator按钮上显示自定义标题和图形,您需要设置一些标志符号。您可以使用TImageList组件并指定10个图片(.bmp或.ico),每个图片表示DBNavigator的特定按钮的动作。

第三,在Form1的OnCreate事件中,添加如下调用:

procedure TForm1.FormCreate(Sender: TObject); SetupHackedNavigator(DBNavigator1, ImageList1);end;

确保在表单声明的私有部分添加此过程的声明,如:

type TForm1 = class(TForm) ... privateprocedure SetupHackedNavigator(const Navigator : TDBNavigator; const Glyphs : TImageList); ...

第四,添加SetupHackedNavigator过程。SetupHackedNavigator过程为每个按钮添加自定义图形,并为每个按钮指定自定义标题。

uses Buttons; //!!! don't forgetprocedure TForm1.SetupHackedNavigator (const Navigator : TDBNavigator; const Glyphs : TImageList);const Captions : array[TNavigateBtn] of string = ('Initial', 'Previous', 'Later', 'Final', 'Add', 'Erase', 'Correct', 'Send', 'Withdraw', 'Revive');(* Captions : array[TNavigateBtn] of string = ('First', 'Prior', 'Next', 'Last', 'Insert', 'Delete', 'Edit', 'Post', 'Cancel', 'Refresh'); in Croatia (localized): Captions : array[TNavigateBtn] of string = ('Prvi', 'Prethodni', 'Slijedeci', 'Zadnji', 'Dodaj', 'Obrisi', 'Promjeni', 'Spremi', 'Odustani', 'Osvjezi');*)var btn : TNavigateBtn;beginfor btn := Low(TNavigateBtn) to High(TNavigateBtn) dowith THackDBNavigator(Navigator).Buttons[btn] dobegin//from the Captions const array Caption := Captions[btn]; //the number of images in the Glyph property NumGlyphs := 1; // Remove the old glyph. Glyph := nil; // Assign the custom one Glyphs.GetBitmap(Integer(btn),Glyph); // gylph above text Layout := blGlyphTop; // explained later OnMouseUp := HackNavMouseUp; end;end; (*SetupHackedNavigator*)

好的,让我们解释一下。遍历DBNavigator中的所有按钮。回想一下,每个按钮都可以从protected Buttons数组属性访问,因此不需要THackDBNavigator类。因为按钮数组的类型是TNavigateBtn,所以从“第一个”(使用低功能)按钮转到“最后一个”(使用高功能)按钮。对于每个按钮,只需删除“旧”字形,分配新字形(从Glyphs参数),从Captions数组添加标题,并标记字形的布局。

请注意,您可以通过DBNavigator的VisibleButtons属性来控制DBNavigator(而不是黑客)显示哪些按钮。另一个属性的默认值可能需要更改为提示。使用该属性可以为单个导航器按钮提供您选择的帮助提示。您可以通过编辑ShowHits属性来控制提示的显示。

就这样。这就是你选择德尔福的原因!

再给我一点!

为什么停在这里?您知道,当您单击“nbNext”按钮时,数据集的当前位置将前进到下一条记录。如果用户在按住CTRL键的同时按下按钮,那么您想向前移动5条记录,该怎么办?怎么样?

“标准”DBNavigator没有OnMouseUp事件,该事件带有TSShift状态的Shift参数,使您能够测试Alt、Ctrl和Shift键的状态。DBNavigator只提供OnClick事件供您处理。

但是,THackDBNavigator可以简单地公开OnMouseUp事件,使您能够“查看”控制键的状态,甚至在单击特定按钮时光标的位置!

按住ctrl键并单击:=前面5行

要公开OnMouseUp,只需将自定义事件处理过程分配给被黑客攻击的DBNavigator按钮的OnMouseUp事件。这已经在SetupHackedNavigator过程中完成了:OnMouseUp:=HackNavMouseUp;

现在,HackNavMouseUp过程可能看起来像:

procedure TForm1.HackNavMouseUp (Sender:TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);const MoveBy : integer = 5;beginif NOT (Sender is TNavButton) then Exit; case TNavButton(Sender).Index of nbPrior: if (ssCtrl in Shift) then TDBNavigator(TNavButton(Sender).Parent). DataSource.DataSet.MoveBy(-MoveBy); nbNext: if (ssCtrl in Shift) then TDBNavigator(TNavButton(Sender).Parent). DataSource.DataSet.MoveBy(MoveBy); end; end;(*HackNavMouseUp*)

注意,您需要在表单声明的私有部分(靠近SetupHackedNavigator过程的声明)中添加HackNavMouseUp过程的签名:

type TForm1 = class(TForm) ... privateprocedure SetupHackedNavigator(const Navigator : TDBNavigator; const Glyphs : TImageList); procedure HackNavMouseUp(Sender:TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); ...

好吧,让我们再解释一遍。HackNavMouseUp过程处理每个DBNavigator按钮的OnMouseUp事件。如果用户在按住CTRL键的同时单击nbNext按钮,则链接数据集的当前记录将被移动到“MoveBy”(定义为常量,值为5)记录的前面。

什么?过于复杂?

是的。如果您只需要在单击按钮时检查控制键的状态,则无需处理所有这些。下面是如何在“普通”DBNavigator的“普通”OnClick事件中执行相同操作:

procedure TForm1.DBNavigator1Click(Sender: TObject; Button: TNavigateBtn); function CtrlDown : Boolean; var State : TKeyboardState; begin GetKeyboardState(State); Result := ((State[vk_Control] And 128) 0); end;const MoveBy : integer = 5;begincase Button of nbPrior: if CtrlDown then DBNavigator1.DataSource.DataSet.MoveBy(-MoveBy); nbNext: if CtrlDown then DBNavigator1.DataSource.DataSet.MoveBy(MoveBy); end; //caseend;(*DBNavigator2Click*)

这就是所有的人

最后,项目完成了。或者你可以继续。以下是一个场景/任务/想法:

假设您只需要一个按钮来替换nbFirst、nbPrevious、nbNext和nbLast按钮。您可以在HackNavMouseUp过程中使用X和Y参数来查找释放按钮时光标的位置。现在,在这一个按钮(“对所有按钮进行规则化”)上,您可以附加一张有4个区域的图片,每个区域假设模仿您要替换的按钮之一。。。明白了吗?

  • 发表于 2021-09-10 22:21
  • 阅读 ( 220 )
  • 分类:编程

你可能感兴趣的文章

如何在googlechrome中修复和使用自定义搜索关键字

...ikade”搜索维基百科中的“chikade”或“h windows”,以搜索如何极客获取有关windows的文章。 你可以在Chrome中通过点击菜单>设置>搜索引擎>管理搜索引擎来控制这些。“关键字”字段定义启动自定义搜索的自定义关键字。加...

  • 发布于 2021-03-31 15:24
  • 阅读 ( 147 )

如何将窗口捕捉到Windows10上的自定义屏幕区域

...ve swapped out screenshots and tweaked the steps to match the new version. 如何自定义windows 10的捕捉功能 内置的Snap-Assist功能只适用于2×2的网格布局,这意味着窗口的大小将始终相等,以适应该区域:两个窗口并排,四个窗口位于屏幕的四个角...

  • 发布于 2021-03-31 19:05
  • 阅读 ( 197 )

如何在office 2013中自定义功能区上的现有选项卡

默认情况下,Microsoft Office 2013中的功能区提供了对许多功能和选项的快速访问,但可以进一步自定义以适应您的使用方式。可以向功能区中添加自定义选项卡,也可以向现有选项卡中添加命令。 要将命令添加到功能区上现有的...

  • 发布于 2021-04-10 20:38
  • 阅读 ( 179 )

microsoft word的自定义词典位于哪里?

...驱动的问答网站分组。 问题 超级用户读者Shaqpad想知道如何在Microsoft Office中查找和保存自定义词典单词列表: I use Microsoft Office Proofing Tools, but have run into a problem now that I have to re-install Windows. After I re-install Windows, the custom list of...

  • 发布于 2021-04-11 10:29
  • 阅读 ( 147 )

充分利用microsoft office的10个快速提示

...ands. 通过在Office2007中自定义快速访问工具栏来节省时间 如何备份和恢复office 2010功能区和快速访问工具栏自定义设置 Now, that you learned how to create custom tabs on the Office 2010 Ribbon and how to customize the Quick Access Toolbar, you can backup both the...

  • 发布于 2021-04-12 17:08
  • 阅读 ( 258 )

问如何极客:停止自动ie更新,自定义Windows7文件夹背景,自定义ubuntu引导加载

...将能够改变字体,背景想象,等等。 有一个问题你想问如何极客员工?给我们发邮件询问@tl80.cn然后在“询问如何极客”专栏中寻找解决方案。

  • 发布于 2021-04-12 23:35
  • 阅读 ( 144 )

如何定制你的ubuntu内核

...核以支持当前运行的内核不支持的硬件。 本文将不解释如何修补内核,只解释如何定制当前内核。我将有另一篇后续文章来解释如何修补内核,以及为什么要这么做的一些实际原因。 首先,我们需要弄清楚当前运行的内核版本...

  • 发布于 2021-04-14 15:16
  • 阅读 ( 133 )

在firefox中设置自定义新标签页

...的快速拨号标签的忠实粉丝,Mozilla博客Mozilla Links展示了如何通过对页面的简单编辑来定制页面,以加载你选择的任何站点about:config file.要创建自定义的新选项卡页,您只需编辑一个文件,操作简单:Go to advanced preferences entering a...

  • 发布于 2021-05-26 09:09
  • 阅读 ( 117 )

用户控件(user control)和自定义控件(custom control)的区别

关键区别:在ASP.net framework中,用户控件和自定义控件用于将可重用组件用作控件。用户控件的创建就像web窗体一样。它们利用现有的控件来定义自己的逻辑。另一方面,自定义控件是由程序员创建的,通过扩展现有控件的功能...

  • 发布于 2021-07-13 20:49
  • 阅读 ( 179 )

如何在apple watch上设置自定义计时器

... Siri on Apple Watch How to Monitor the Timer on Your Apple Watch Face 如何快速启动apple watch上的预设计时器 Apple Watch的内置计时器应用程序可以快速访问常用的计时器设置。要使用它们,请抬起Apple Watch并按下数字表冠。然后,从应用程序...

  • 发布于 2021-07-14 18:32
  • 阅读 ( 103 )
是可爱的苏念
是可爱的苏念

0 篇文章

相关推荐