来自:独帅, 时间:2003-11-24 18:59:00, ID:2314283
我写完了大部分的代码,稍微修改一下就可以用了。
使用方法如下:
procedure TForm1.Button1Click(Sender: TObject);
begin
RegJump('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run');
end;
另外,看一下ValidRegString函数就知道,我只写了HKEY_LOCAL_MACHINE、
HKEY_CURRENT_USER、HKEY_CLASSES_ROOT等三种常见的情况,其他的几种自己写完吧
还有,后面有一段代码,可以选中注册表窗口右面指定的键值(Value),需要的话自己完成吧(参考上面的)
Type
TRegType = (rtInvalid, rtHKCR, rtHKCU, rtHKLM, rtHKCC, rtHKU);
function ValidRegString(const RegString: String): TRegType;
var
h: HKEY;
lRoot: DWORD;
lRegString: String;
begin
Result := rtInvalid;
lRoot := HKEY_LOCAL_MACHINE;
lRegString := UpperCase(RegString);
if Pos('HKEY_LOCAL_MACHINE', lRegString) = 1 then
begin
Result := rtHKLM;
lRoot := HKEY_LOCAL_MACHINE;
lRegString := StringReplace(RegString, 'HKEY_LOCAL_MACHINE\', '', [rfIgnoreCase]);
end
else if Pos('HKEY_CURRENT_USER', lRegString) = 1 then
begin
Result := rtHKCU;
lRoot := HKEY_CURRENT_USER;
lRegString := StringReplace(RegString, 'HKEY_CURRENT_USER\', '', [rfIgnoreCase]);
end
else if Pos('HKEY_CLASSES_ROOT', lRegString) = 1 then
begin
Result := rtHKCR;
lRoot := HKEY_CLASSES_ROOT;
lRegString := StringReplace(RegString, 'HKEY_CLASSES_ROOT\', '', [rfIgnoreCase]);
end;
if (Result <> rtInvalid) and (RegOpenKeyEx(lRoot, PChar(lRegString), 0, KEY_ALL_ACCESS, h) = ERROR_SUCCESS) then
RegCloseKey(h)
else
Result := rtInvalid;
end;
procedure RegJump(const RegString: String);
const
REGEDITSLOWWAIT = 750;
var
lRegString: String;
devMode: TDEVMODE;
regeditHwnd, regeditMainHwnd: HWND;
info: TSHELLEXECUTEINFO;
i, vk: Integer;
c: Char;
begin
if (ValidRegString(RegString) = rtInvalid) then
begin
//RegString 不是合法的注册表字符串
Exit;
end;
// Get the color depth, which can effect the speed that Regedit
// responds to keyboard commands
devMode.dmSize := sizeof(TDEVMODE);
//EnumDisplaySettings(nil, ENUM_CURRENT_SETTINGS, devMode );
EnumDisplaySettings(nil, 0, devMode );
// Open RegEdit
regeditMainHwnd := FindWindow( 'RegEdit_RegEdit', nil);
if ( regeditMainHwnd <= 0 ) then
begin
FillChar(info, SizeOf(info), 0);
info.cbSize := sizeof(info);
info.fMask := SEE_MASK_NOCLOSEPROCESS;
info.lpVerb := 'open';
info.lpFile := 'regedit.exe';
info.nShow := SW_SHOWNORMAL;
ShellExecuteEx(@info);
WaitForInputIdle( info.hProcess, INFINITE );
regeditMainHwnd := FindWindow( 'RegEdit_RegEdit', nil);
end;
if ( regeditMainHwnd <= 0 ) then Exit;//unable to launch Regedit.
ShowWindow( regeditMainHwnd, SW_SHOW );
SetForegroundWindow( regeditMainHwnd );
// Get treeview
regeditHwnd := FindWindowEx( regeditMainHwnd, 0, 'SysTreeView32', nil );
SetForegroundWindow( regeditHwnd );
SetFocus( regeditHwnd );
// Close it up
for i:= 0 to 30 do
begin
vk := VK_LEFT;
SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
end;
// wait for slow displays -
// Regedit takes a while to open keys with lots of subkeys
// when running at high color depths
if ( devMode.dmBitsPerPel > 8 ) then Sleep(REGEDITSLOWWAIT);
// Open path
lRegString := '\' + RegString;
for i:= 1 to Length(lRegString) do
begin
c := lRegString[i];
if c = '\' then
begin
vk := VK_RIGHT;
SendMessage(regeditHwnd, WM_KEYDOWN, vk, 0);
// wait for slow displays -
// Regedit takes a while to open keys with lots of subkeys
// when running at high color depths
if ( devMode.dmBitsPerPel > 8 ) then Sleep(REGEDITSLOWWAIT);
end
else
begin
vk := Ord(UpCase(c));
SendMessage(regeditHwnd, WM_CHAR, vk, 0);
end;
end;
////////////////////////////////////////////////////////////////////////////////
//原来这个地方还有一部分代码,可以选中注册表窗口右面指定的键值(Value),不写了.//
////////////////////////////////////////////////////////////////////////////////
SetForegroundWindow( regeditMainHwnd );
SetFocus( regeditMainHwnd );
end;
---------------------------------------
可以参考www.sysinternals.com 的Regmon,在Regmon.c中有个函数RegeditJump就实现了你要的功能:
/******************************************************************************
*
* Regmon - Registry Monitor for Windows 95/98/Me/NT/2K/XP/IA64
*
* Copyright (c) 1996-2002 Mark Russinovich and Bryce Cogswell
*
* See readme.txt for terms and conditions.
*
* PROGRAM: Regmon.c
*
* PURPOSE: Communicates with the RegMon driver to display
* registry activity information.
*
******************************************************************************/
/******************************************************************************
*
* FUNCTION: RegeditJump
*
* PURPOSE: Opens Regedit and navigates the desired key
*
*****************************************************************************/
void RegeditJump( HWND hWnd )
{
int currentItem;
int pos;
char * ch;
HWND regeditHwnd, regeditMainHwnd;
char compressPath[MAX_PATH];
HKEY hKey;
char *value = NULL;
DWORD status;
char RegPath[MAX_PATH];
DEVMODE devMode;
// Get the color depth, which can effect the speed that Regedit
// responds to keyboard commands
devMode.dmSize = sizeof(DEVMODE);
EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &devMode );
// See if we can get a Registry path out of the listview
// find the item with the focus
currentItem = ListView_GetNextItem( hWndList, -1, LVNI_SELECTED );
if( currentItem == -1 ) {
MessageBox( hWnd, "No item selected.", APPNAME, MB_OK|MB_ICONWARNING );
return;
}
memset( compressPath, 0, MAX_PATH );
ListView_GetItemText( hWndList, currentItem, 4, compressPath, MAX_PATH );
// If the key is a handle reference, tell the user we're sorry
if( compressPath[0] == '0' ) {
MessageBox( hWnd, "The full name of the selected key or value is not available.",
APPNAME, MB_OK|MB_ICONWARNING );
return;
}
// We need to uncompress abbreviations
if( !strncmp( compressPath, "HKLM", strlen("HKLM"))) {
sprintf( RegPath, "\\HKEY_LOCAL_MACHINE%s", &compressPath[strlen("HKLM")] );
status = RegOpenKey( HKEY_LOCAL_MACHINE, &compressPath[strlen("HKLM")+1], &hKey );
} else if( !strncmp( compressPath, "HKCU", strlen("HKCU"))) {
sprintf( RegPath, "\\HKEY_CURRENT_USER%s", &compressPath[strlen("HKCU")] );
status = RegOpenKey( HKEY_CURRENT_USER, &compressPath[strlen("HKCU")+1], &hKey );
} else if( !strncmp( compressPath, "HKCC", strlen("HKCC"))) {
sprintf( RegPath, "\\HKEY_CURRENT_CONFIG%s", &compressPath[strlen("HKCC")] );
status = RegOpenKey( HKEY_CURRENT_CONFIG, &compressPath[strlen("HKCC")+1], &hKey );
} else if( !strncmp( compressPath, "HKCR", strlen("HKCR"))) {
sprintf( RegPath, "\\HKEY_CLASSES_ROOT%s", &compressPath[strlen("HKCR")] );
status = RegOpenKey( HKEY_CLASSES_ROOT, &compressPath[strlen("HKCR")+1], &hKey );
} else if( !strncmp( compressPath, "HKU", strlen("HKU"))) {
sprintf( RegPath, "\\HKEY_USERS%s", &compressPath[strlen("HKU")] );
status = RegOpenKey( HKEY_USERS, &compressPath[strlen("HKU")+1], &hKey );
} else {
strcpy( RegPath, compressPath );
status = FALSE;
}
// Is it a value or a key?
if( status == ERROR_SUCCESS ) {
RegCloseKey( hKey );
strcat( RegPath, "\\" );
} else {
value = strrchr( RegPath, '\\')+1;
*strrchr( RegPath, '\\' ) = 0;
}
// Open RegEdit
regeditMainHwnd = FindWindow( "RegEdit_RegEdit", NULL );
if ( regeditMainHwnd == NULL ) {
SHELLEXECUTEINFO info;
memset( &info, 0, sizeof info );
info.cbSize = sizeof info;
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.lpVerb = "open";
info.lpFile = "regedit.exe";
info.nShow = SW_SHOWNORMAL;
ShellExecuteEx( &info );
WaitForInputIdle( info.hProcess, INFINITE );
regeditMainHwnd = FindWindow( "RegEdit_RegEdit", NULL );
}
if( regeditMainHwnd == NULL ) {
MessageBox( hWnd, "Regmon was unable to launch Regedit.",
APPNAME, MB_OK|MB_ICONERROR );
return;
}
ShowWindow( regeditMainHwnd, SW_SHOW );
SetForegroundWindow( regeditMainHwnd );
// Get treeview
regeditHwnd = FindWindowEx( regeditMainHwnd, NULL, "SysTreeView32", NULL );
SetForegroundWindow( regeditHwnd );
SetFocus( regeditHwnd );
// Close it up
for ( pos = 0; pos < 30; ++pos ) {
UINT vk = VK_LEFT;
SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
}
// wait for slow displays -
// Regedit takes a while to open keys with lots of subkeys
// when running at high color depths
if( devMode.dmBitsPerPel > 8 ) Sleep(REGEDITSLOWWAIT);
// Open path
for ( ch = RegPath; *ch; ++ch ) {
if ( *ch == '\\' ) {
UINT vk = VK_RIGHT;
SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
// wait for slow displays -
// Regedit takes a while to open keys with lots of subkeys
// when running at high color depths
if( devMode.dmBitsPerPel > 8 ) Sleep(REGEDITSLOWWAIT);
} else {
UINT vk = toupper(*ch);
SendMessage( regeditHwnd, WM_CHAR, vk, 0 );
}
}
// If its a value select the value
if( value ) {
UINT vk = VK_HOME;
regeditHwnd = FindWindowEx( regeditMainHwnd, NULL, "SysListView32", NULL );
SetForegroundWindow( regeditHwnd );
SetFocus( regeditHwnd );
Sleep(1000); // have to wait for Regedit to update listview
SendMessage( regeditHwnd, WM_KEYDOWN, vk, 0 );
for ( ch = value; *ch; ++ch ) {
UINT vk = toupper(*ch);
SendMessage( regeditHwnd, WM_CHAR, vk, 0 );
}
}
SetForegroundWindow( regeditMainHwnd );
SetFocus( regeditMainHwnd );
}