2013-09-20 6 views
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; 

Если у вас есть лучший способ, пожалуйста, дайте мне знать.


Использование Delphi XE, Win 7

+0

Ваша первая попытка не удалась на 'ERROR_FILE_NOT_FOUND'. – TLama

+0

Все работает отлично. Я отмечаю, что ваши две версии делают разные вещи. –

+0

@DavidHeffernan - Да, второй лучше, потому что WinExec отмечен как устаревший. – Ampere

ответ

4

Я получил control.exe метод работает отлично себя, но так как я чувствовал потребность играть, вы можете вызвать элемент панели управления непосредственно. Тем не менее, вы используете метод, который используется, когда вы call control panel items using 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; 

удовольствие.

Смежные вопросы