我正在重做一些代码以准备好 64 位。这使用带有回调的 EnumWindows 来返回列表 运行 delphi 应用程序(除了 IDE 和它本身)然后被杀死。起初 它使用 TStringlist 来保存这些应用程序的句柄。我想更改它以直接以数字形式收集句柄。 我使用通用 TList 收集句柄,得出了一个非常令人满意的解决方案,如下所示。
在此过程中,我最初尝试使用动态数组 - 它没有用。验证了TList的解法后,出于学术兴趣,重温了一下, 尝试了各种方法来使用动态数组来实现它——但都没有成功。我在文档中找不到任何禁令,尽管我确实遇到过 Rudy V 博客中的这条注释:“无论如何,Delphi 字符串和动态数组不应作为引用计数类型传递给 API 函数……”
所以,我只是在寻求一个“裁决”,即动态数组可以或不能用作回调函数的参数。
type
THandleList=Tlist<THandle>;
const
ReqdClass: string = 'TApplication' ;
procedure KillWindowViaHandle(Ahwnd:THandle; Amsg: Cardinal=WM_CLOSE);
begin
PostMessage(Ahwnd, Amsg, 0, 0);
end;
// Get Active "User" Applications (except for bds.exe & caller). Relies on top
// level window having classname of TApplication. Returns list of handles.
function FindActiveUSERApps(AHandle: HWND; AList: lparam): BOOL ; stdcall;
var
classname: string;
pid: DWORD;
imagename: string;
begin
Result := true; // keep it going .. want them all
GetWindowThreadProcessID(AHandle, @pid); // not interested in ThreadID returned
imagename := GetProcessFileName(pid) ;
SetLength(ClassName, 255);
SetLength(ClassName, GetClassName(AHandle, PChar(className), Length(className)));
if ( ansicontainstext(classname, ReqdClass) ) and
( not ansisametext(ImageName, 'bds.exe')) and
( not ansisametext(ImageName, ExtractFileName(Application.ExeName))) then
THandleList(Alist).Add(AHandle) ;
end;
function GetActiveUSERApps(AList: THandleList): boolean;
begin
AList.Clear;
EnumWindows(@FindActiveUSERApps, lparam(AList) );
result := Alist.Count > 0;
end;
function KillActiveUSERApps: boolean;
var
i : integer;
ActiveList: THandleList;
begin
result := false;
ActiveList := THandleList.Create;
try
GetActiveUSERApps(ActiveList);
for i:= 0 to activelist.Count - 1 do
KillWindowviaHandle( ActiveList[i] );
// noticed that some processes were resistant to being killed via WM_CLOSE.
// So try gentle approach first, and then if necessary, use the big stick.
GetActiveUSERApps(activeList);
for i:= 0 to activelist.Count - 1 do
KillWindowviaHandle( ActiveList[i], WM_QUIT );
result := true;
finally
ActiveList.Free;
end;
end;
最佳答案
在没有实际看到您使用动态数组的实现的情况下,我假设您通过使用 SetLength 扩展它来向该数组添加元素。这反过来又改变了内部是指针的数组变量。因此,调用方法仍然使用指向它作为参数传递的不存在的动态数组的旧指针变量。
您可以通过使用指向动态数组的指针来解决这个问题。
type
THandleList = TArray<THandle>;
PHandleList = ^THandleList;
function FindActiveUSERApps(AHandle: HWND; AList: lparam): BOOL ; stdcall;
var
...
PList: PHandleList;
begin
...
PList := PHandleList(AList);
SetLength(PList^, Length(PList^) + 1);
PList^[High(PList^)] := AHandle;
end;
function GetActiveUSERApps(var AList: THandleList): boolean;
begin
AList.Clear;
EnumWindows(@FindActiveUSERApps, lparam(@AList) );
result := Alist.Count > 0;
end;
也就是说,我个人更喜欢 TList 方法,因为它简单明了。特别是因为您可以使用 AList.ToArray 轻松地从中返回一个动态数组。
关于arrays - 动态数组可以用作 Windows 回调函数的参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42320531/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这