0

我想从控制面板执行一个项目(例如“屏幕分辨率”)。 MS说WinExec应该很容易。

这些尝试将起作用(打开 CPanel),但之后 IDE 将立即崩溃(在 BorDbk150N.dll 中崩溃):

procedure ProjectTest1;
VAR s: AnsiString;
begin
 s:= 'c:\windows\system32\control.exe Desk.cpl,Settings';
 WinExec(pansichar(s), SW_NORMAL);
end;



procedure ProjectTest2;
VAR
  App        : String;
  Params     : String;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  try
   App    := 'c:\windows\system32\control.exe';
   Params := 'desk.cpl,Settings';
   FillChar(StartupInfo, SizeOf(StartupInfo), 0);
   StartupInfo.cb := SizeOf(StartupInfo);
   if NOT CreateProcess(NIL, PChar(App+' '+Params), nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo) then RaiseLastOSError;
  except
    on E: Exception do
     Writeln(E.ClassName, ': ', E.Message);
  end;
end;

如果你有更好的方法请告诉我。


使用德尔福 XE,Win 7

4

1 回答 1

5

我自己的control.exe方法运行良好,但由于我觉得有必要玩,您实际上可以直接调用控制面板项。也就是说,您使用的是在使用 RUNDLL32 调用控制面板项时使用的方法。

Display Properties (Settings):
    rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3

代码在这里。我针对一些控制面板项目对其进行了测试,它是否普遍适用是另一回事(以及我是否完成了所有错误检查),但它在我抛出的所有情况下都有效,包括所有桌面设置选项卡。

function CallControlPanel(Handle: HWnd; FileName, FuncCall: WideString): Integer;
{
   calls a control panel item described in the function parms, if it supports
   being called using RUNDLL32.
   Handle: Valid window handle to parent form.
   FileName: Name of the Control Panel Applet, e.g. desk.cpl
   FuncCall: Alias call name for the tab requested e.g. "@Themes" or "1";
             What is put here is dependent on what the control panel app supports.
   Result: -1 if calls don't work, otherwise result of control panel call
}

const
  CPL_STARTWPARMSW = 10;
type
  cplfunc = function (hWndCPL : hWnd; iMessage : integer; lParam1 : longint;
         lParam2 : longint) : LongInt stdcall;
var
  lhandle: THandle;
  funchandle: cplfunc;
begin
  Result := -1;
  lHandle := LoadLibraryW(PWideChar(FileName));
  if LHandle <> 0 then
    begin
      @funchandle := GetProcAddress(lhandle, 'CPlApplet');
      if @funchandle <> nil then
        Result := funchandle(Handle, CPL_STARTWPARMSW, 0, LongInt(PWideString(funccall)));
      FreeLibrary(lHandle);
    end;
end;

示例调用:

procedure TForm1.Button2Click(Sender: TObject);
begin
  CallControlPanel(Handle, 'desk.cpl', '@ScreenSaver');
  CallControlPanel(Handle, 'desk.cpl', '@Themes');
  CallControlPanel(Handle, 'access.cpl', '1');  // doesn't support @ aliases
  CallControlPanel(Handle, 'access.cpl', '3');
  CallControlPanel(Handle, 'access.cpl', '5');
end;

玩得开心。

于 2013-09-20T16:49:34.140 回答