我知道我可以调用GetVersionEx Win32 API函数来检索Windows版本.在大多数情况下,返回值反映了我的Windows版本,但有时并非如此.
如果用户在兼容层下运行我的应用程序,则GetVersionEx将不报告实际版本,而是报告兼容层强制执行的版本.例如,如果我正在运行Vista并在"Windows NT 4"兼容模式下执行我的程序,则GetVersionEx将不会返回版本6.0而是4.0.
有没有办法绕过这种行为并获得真正的Windows版本?
使用构造函数或实例函数复制对象实例的优缺点是什么?
例A:
type
TMyObject = class
strict private
FField: integer;
public
constructor Create(srcObj: TMyObject); overload;
//alternatively:
//constructor CreateFrom(srcObj: TMyObject);
property Field: integer read FField;
end;
constructor TMyObject.Create(srcObj: TMyObject);
begin
inherited Create;
FField := srcObj.Field;
end;
Run Code Online (Sandbox Code Playgroud)
例B:
type
TMyObject = class
strict private
FField: integer;
public
function Clone: TMyObject;
property Field: integer read FField;
end;
function TMyObject.Clone: TMyObject;
begin
Result := TMyObject.Create;
Result.FField := FField;
end;
Run Code Online (Sandbox Code Playgroud)
一个主要的区别立即浮出水面 - 在后一种情况下,Create构造函数必须是虚拟的,以便可以基于TMyObject构建支持Clone的类层次结构.
假设这不是问题 - TMyObject和基于它的所有内容完全在我的控制之下.在Delphi中进行复制构造函数的首选方法是什么?您觉得哪个版本更具可读性?你什么时候使用前者或后者?讨论.:)
编辑:我对第一个例子的主要关注是,与第二种方法相比,使用率非常高,即
newObj := TMyObject.Create(oldObj)
Run Code Online (Sandbox Code Playgroud)
与
newObj := oldObj.Clone;
Run Code Online (Sandbox Code Playgroud)
EDIT2或"我为什么要单行操作" …
单击button1放置后form1,程序正在检查新版本是否可用(通过互联网),但是在新线程中执行此操作(在检查期间不冻结表单).
当找到新版本时,MessageBox会显示相应的版本,但它没有父版本(因为它是从线程调用的,而不是直接从调用中调用的form1).
如何作为父母进行MessageBox显示form1?
当有大量文件活动时,互联网上有很多关于ReadDirectoryChangesW API函数丢失文件的帖子.大多数人都指责调用ReadDirectoryChangesW函数循环的速度.这是一个不正确的假设.我看到的最好的解释是在下面的帖子,评论于2008年4月14日星期一下午2:15:27
http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/4465cafb-f4ed-434f-89d8-c85ced6ffaa8/
摘要是ReadDirectoryChangesW函数报告文件更改,因为它们离开文件后写队列,而不是添加它们.如果在提交之前添加了太多,则会忽略其中一些.如果您只是编写一个程序来快速生成目录中的1000多个文件,您可以通过实现看到这一点.只需计算您获得的文件事件通知数量,您就会看到有时您不会收到所有这些通知.
问题是,有没有人找到一种可靠的方法来使用ReadDirectoryChangesW函数而不必每次都刷新卷?如果用户不是管理员并且还可能需要一些时间来完成,则不允许这样做.
我有一个类(TObject):
private
FHwnd : HWND;
procedure HandleMyMessage(var Message : TMessage); message TH_MYMESSAGE;
Run Code Online (Sandbox Code Playgroud)
哪里 TH_MYMESSAGE = WM_USER + 1
在类构造函数中:
FHwnd := AllocateHWND(HandleMyMessage);
Run Code Online (Sandbox Code Playgroud)
接收引用的唯一对象FHwnd是私有自定义TThread(在此类中创建)以及它发布的唯一消息TH_MYMESSAGE.我的理解是,message程序声明中的指令仅限制其处理TH_MYMESSAGE.
这在测试中运行良好,但是在集成到更大的应用程序中时,我得到的反馈HandleMyMessage也会触发其他消息(显然有不希望的结果).
这可以通过添加if Message.Msg <> TH_MYMESSAGE then Exit;来轻松纠正HandleMyMessage.我的问题是:为什么会这样?
我最好的猜测是,AllocateHWND已经取得HandleMyMessage的等效DefWndProc尽管拥有它message的指令.有没有正确的方法来实现我缺少的?
我们使用以下函数来获取当前引导配置指定的处理器数.此数字仅用于记录.
以下功能适用于XP,Vista,7,2003和2008.但是,它在Windows 2012 Server上失败.
// -1 = not implemented or not allowed
// 0 = not limited
// >0 = number of processors in the {current} boot entry
function Internal_GetBCDNumberOfProcessors: integer;
var
objBcdStore : OleVariant;
objElement : OleVariant;
objWBL : OleVariant;
objWMIService: OleVariant;
begin
// for more info, see: http://stackoverflow.com/questions/7517965/accessing-bcdstore-from-delphi/7527164#7527164
Result := -1;
try
objWMIService := GetObject('winmgmts:{(Backup,Restore)}\\.\root\wmi:BcdStore');
if (not VarIsNull(objWMIService)) and
boolean(objWMIService.OpenStore('', objBcdStore)) and
(not VarIsNull(objBcdStore)) and
boolean(objBcdStore.OpenObject('{fa926493-6f1c-4193-a414-58f0b2456d1e}', objWBL)) and
(not VarIsNull(objWBL))
then
if objWBL.GetElement($25000061, objElement) and //<-- fails here …Run Code Online (Sandbox Code Playgroud) 我正在寻找OS X上的MessageBeep替换.似乎调用的正确函数是NSBeep但是XE2 RTL不支持它.
如何从Delphi应用程序中调用NSBeep?
在Delphi中定义的过程调用之前,是否计算参数的顺序?
IOW,如果我有这个丑陋的代码(在遗留应用程序中找到类似的东西)......
function A(var err: integer): integer;
begin
err := 42;
Result := 17;
end;
Test(A(err), err);
Run Code Online (Sandbox Code Playgroud)
...测试保证接收参数(17,42)还是(17,未定义)?
编辑:
虽然David的示例在32位和64位编译器中返回不同的结果,但这(幸运的是)不会影响我的遗留代码,因为Test(A(错误),错误)只在寄存器中存储'err' 的地址无论编译器在调用A(错误)之前还是之后执行此操作都无关紧要.
Word 2010中的"选项"对话框通过一组白色"切换"按钮实现类别选择器,这些按钮在单击(选中)时变为橙色.

如何在Delphi中重新实现这种行为?需要符合当前的Windows主题(即必须可以将按钮颜色指定为clWindow,而不是clWhite).
编辑:澄清 - 我只有左侧的类别选择器有问题.其他一切都相当简单.
我正在尝试编译一个包含DSUtils.pas(DSPack的一部分)的软件包,它失败了,因为它试图编译错误的DirectShow9.pas单元 - 不是DSPack中的那个,而是来自Delphi XE2(Update 3)RTL的那个.
使用最小包装可以重复该问题:
package Package1;
{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$IMPLICITBUILD ON}
requires
rtl;
contains
DSUtils in 'x:\common\pkg\dspack\src\DSPack\DSUtils.pas';
end.
Run Code Online (Sandbox Code Playgroud)
DSUtils行1058中发生错误,错误是Undeclared identifier: …