如何执行控制面板中的项目?

WeG*_*ars 0 delphi

我想从控制面板执行一个项目(例如“屏幕分辨率”)。 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;
Run Code Online (Sandbox Code Playgroud)

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


使用 Delphi XE,Win 7

Gle*_*234 5

我自己弄的 control.exe 方法工作正常,但是因为我觉得需要玩,你实际上可以直接调用控制面板项。也就是说,您使用了使用 RUNDLL32 调用控制面板项时使用的方法。

Display Properties (Settings):
    rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)

示例调用:

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;
Run Code Online (Sandbox Code Playgroud)

玩得开心。