前段时间我的火狐彻底无法启动了,万般无奈下花了很大的力气转投Chrome
Chrome有很多地方不符合我的使用习惯,虽然可换枫树浏览器,这方面她做得很好,但我更希望使用原版的Chrome
不符习惯的问题中有个很典型的就是:在鼠标左键点击书签栏的书签时,新标签页会替换当前标签页,使用中键点击才会另新建标签页
(注意区分书签和标签)
这点非常不好,非常不符习惯。在改习惯和改程序直接,我选择了后者
好在Chrome是开源的,不然我可能要多花三四天的时间,但是开源的也没我想的那么简单
代码有4G多,想找点什么真是大海捞针。而且我又无法编译代码,因为它需要很多工具比如SVN什么的,我这里全部没有,只能干看
我在这里做个简易教程,把关键点提出来,主要是为应付以后版本更新,大家可自行修改。别看文章有点长,其实我没说过几句话
----------------------------------------------------------------------------------------------------
(此代码在文件\chromium\src\ui\views\controls\menu\menu_runner.cc)
你可能觉得,这些代码看不懂。其实完全不用看懂,不过是一些代码片段,有什么理解必要?你只要看懂我在讲什么就行了
上面两条函数中出现了两个变量,是关键:
<1> disposition_from_event_flags
<2> mouse_event_flags
这两个变量记录的都是用户鼠标点击事件,比如你点的是左键呢,还是中键
为什么要有两个呢,因为对于书签栏中“普通书签按钮”和“菜单书签按钮”,它是分开处理的,所以要修改的地方也就是两处
我多解释一下所谓的“菜单书签按钮”,比如放在书签栏文件夹中的书签按钮就是
那解决方案现在已经非常明显了,用户点击了鼠标左键,我把它改成点击鼠标中键不就达成目的了吗
应该修改的地方,我在上述代码中用注释标明出来了,这里再强调一下
disposition_from_event_flags的推荐修改这里:
OpenURLParams params(
node->url(),
Referrer(),
disposition_from_event_flags, //推荐修改此处
content::PAGE_TRANSITION_AUTO_BOOKMARK, false );
mouse_event_flags的修改这里:
return MenuDone(result, mouse_event_flags); //推荐修改此处
还有最后一个问题,就是这两个变量的取值:
(后者的宏定义在\chromium\src\ui\base\events.h中,前者懒得找了)
----------------------------------------------------------------------------------------------------
还有最后的最后一个问题,就是如何修改
当然是定位汇编来修改,我这里做个简单例子,至于如何定位到这两条函数,大家可以通过函数中的特征码来定位
文件名: Chrome.dll
版本号: 18.0.1025.142
ImageBase:0x57790000
不过我把这些步骤省了,不判断了
对于以上汇编,我做了个补丁,仅供测试之用,放在附注中下载
----------------------------------------------------------------------------------------------------
附注:
http://chromium-browser-source.commondatastorage.googleapis.com/chromium_tarball.html
2012年04月02日
Chrome有很多地方不符合我的使用习惯,虽然可换枫树浏览器,这方面她做得很好,但我更希望使用原版的Chrome
不符习惯的问题中有个很典型的就是:在鼠标左键点击书签栏的书签时,新标签页会替换当前标签页,使用中键点击才会另新建标签页
(注意区分书签和标签)
这点非常不好,非常不符习惯。在改习惯和改程序直接,我选择了后者
我们现在的目标很简单,就是修改原版Chrome,让其左键点击书签栏时新建标签页,而不是替换
好在Chrome是开源的,不然我可能要多花三四天的时间,但是开源的也没我想的那么简单
代码有4G多,想找点什么真是大海捞针。而且我又无法编译代码,因为它需要很多工具比如SVN什么的,我这里全部没有,只能干看
我在这里做个简易教程,把关键点提出来,主要是为应付以后版本更新,大家可自行修改。别看文章有点长,其实我没说过几句话
----------------------------------------------------------------------------------------------------
(此代码在文件\chromium\src\chrome\browser\ui\views\bookmarks\bookmark_bar_view.cc)
void BookmarkBarView::ButtonPressed(views::Button* sender, const views::Event& event)
{
const BookmarkNode* node;
if (sender->tag() == kOtherFolderButtonTag) {
node = model_->other_node();
}
else
{
int index = GetIndexOf(sender);
DCHECK_NE(-1, index);
node = model_->bookmark_bar_node()->GetChild(index);
}
DCHECK(page_navigator_);
//注意disposition_from_event_flags,关键
WindowOpenDisposition disposition_from_event_flags = event_utils::DispositionFromEventFlags(
sender->mouse_event_flags()
);
Profile* profile = browser_->profile();
if (node->is_url())
{
RecordAppLaunch(profile, node->url());
OpenURLParams params( //这是构造函数
node->url(),
Referrer(),
disposition_from_event_flags, //推荐修改此处的disposition_from_event_flags
content::PAGE_TRANSITION_AUTO_BOOKMARK, false );
page_navigator_->OpenURL(params);
}
else
{
bookmark_utils::OpenAll(
GetWidget()->GetNativeWindow(),
profile,
page_navigator_,
node,
disposition_from_event_flags );
}
bookmark_utils::RecordBookmarkLaunch(
IsDetached() ?
bookmark_utils::LAUNCH_DETACHED_BAR : bookmark_utils::LAUNCH_ATTACHED_BAR );
content::RecordAction(UserMetricsAction("ClickedBookmarkBarURLButton"));
}
(此代码在文件\chromium\src\ui\views\controls\menu\menu_runner.cc)
MenuRunner::RunResult MenuRunnerImpl::RunMenuAt(
Widget* parent,
MenuButton* button,
const gfx::Rect& bounds,
MenuItemView::AnchorPosition anchor,
int32 types )
{
if (running_)
{
return MenuRunner::NORMAL_EXIT;
}
MenuController* controller = MenuController::GetActiveInstance();
if (controller)
{
if ((types & MenuRunner::IS_NESTED) != 0)
{
if (!controller->IsBlockingRun()) {
controller->CancelAll();
controller = NULL;
}
}
else
{
controller->CancelAll();
if ((types & MenuRunner::FOR_DROP) == 0) {
return MenuRunner::NORMAL_EXIT;
}
controller = NULL;
}
}
running_ = true;
for_drop_ = (types & MenuRunner::FOR_DROP) != 0;
bool has_mnemonics = (types & MenuRunner::HAS_MNEMONICS) != 0 && !for_drop_;
menu_->PrepareForRun(has_mnemonics, !for_drop_ && ShouldShowMnemonics(button));
//注意mouse_event_flags,关键
int mouse_event_flags = 0;
owns_controller_ = false;
if (!controller)
{
controller = new MenuController(!for_drop_, this);
owns_controller_ = true;
}
controller_ = controller;
menu_->set_controller(controller_);
//参六为返回
MenuItemView* result = controller->Run(parent, button, menu_, bounds, anchor, &mouse_event_flags);
if (for_drop_)
{
return MenuRunner::NORMAL_EXIT;
}
//推荐修改此处的mouse_event_flags
return MenuDone(result, mouse_event_flags);
}
你可能觉得,这些代码看不懂。其实完全不用看懂,不过是一些代码片段,有什么理解必要?你只要看懂我在讲什么就行了
上面两条函数中出现了两个变量,是关键:
<1> disposition_from_event_flags
<2> mouse_event_flags
这两个变量记录的都是用户鼠标点击事件,比如你点的是左键呢,还是中键
为什么要有两个呢,因为对于书签栏中“普通书签按钮”和“菜单书签按钮”,它是分开处理的,所以要修改的地方也就是两处
我多解释一下所谓的“菜单书签按钮”,比如放在书签栏文件夹中的书签按钮就是
那解决方案现在已经非常明显了,用户点击了鼠标左键,我把它改成点击鼠标中键不就达成目的了吗
应该修改的地方,我在上述代码中用注释标明出来了,这里再强调一下
disposition_from_event_flags的推荐修改这里:
OpenURLParams params(
node->url(),
Referrer(),
disposition_from_event_flags, //推荐修改此处
content::PAGE_TRANSITION_AUTO_BOOKMARK, false );
mouse_event_flags的修改这里:
return MenuDone(result, mouse_event_flags); //推荐修改此处
还有最后一个问题,就是这两个变量的取值:
变量 | 左键 | 中键 |
disposition_from_event_flags | 2 | 5 |
mouse_event_flags | 0x10 | 0x20 |
(后者的宏定义在\chromium\src\ui\base\events.h中,前者懒得找了)
----------------------------------------------------------------------------------------------------
还有最后的最后一个问题,就是如何修改
当然是定位汇编来修改,我这里做个简单例子,至于如何定位到这两条函数,大家可以通过函数中的特征码来定位
文件名: Chrome.dll
版本号: 18.0.1025.142
ImageBase:0x57790000
585B3D00 55 push ebp ; BookmarkBarView::ButtonPressed( )
585B3D01 8BEC mov ebp, esp
585B3D03 81EC 78010000 sub esp, 178
585B3D09 A1 00003659 mov eax, dword ptr [59360000]
585B3D0E 33C5 xor eax, ebp
585B3D10 8945 FC mov dword ptr [ebp-4], eax
585B3D13 83A5 F4FEFFFF 0>and dword ptr [ebp-10C], 0
585B3D1A 53 push ebx
585B3D1B 8B5D 08 mov ebx, dword ptr [ebp+8]
585B3D1E 83BB F0000000 0>cmp dword ptr [ebx+F0], 1
585B3D25 56 push esi
585B3D26 57 push edi
585B3D27 8BF1 mov esi, ecx
585B3D29 75 0B jnz short 585B3D36
585B3D2B 8B46 38 mov eax, dword ptr [esi+38]
585B3D2E 8BB8 2C010000 mov edi, dword ptr [eax+12C]
585B3D34 EB 20 jmp short 585B3D56
585B3D36 53 push ebx
585B3D37 8D8E 08FFFFFF lea ecx, dword ptr [esi-F8]
585B3D3D E8 F1E85200 call 58AE2633
585B3D42 8B4E 38 mov ecx, dword ptr [esi+38]
585B3D45 8B89 28010000 mov ecx, dword ptr [ecx+128]
585B3D4B 50 push eax
585B3D4C 83C1 24 add ecx, 24
585B3D4F E8 962920FF call 577B66EA
585B3D54 8B38 mov edi, dword ptr [eax]
585B3D56 FFB3 F4000000 push dword ptr [ebx+F4]
585B3D5C E8 49EBE7FF call 584328AA
585B3D61 83BF B0000000 0>cmp dword ptr [edi+B0], 0
585B3D68 59 pop ecx
585B3D69 8B4E 64 mov ecx, dword ptr [esi+64]
585B3D6C 8B99 C8000000 mov ebx, dword ptr [ecx+C8]
585B3D72 8985 F4FEFFFF mov dword ptr [ebp-10C], eax ; 此变量是disposition_from_event_flags
585B3D78 75 70 jnz short 585B3DEA
585B3D7A 83EC 68 sub esp, 68
585B3D7D 83C7 48 add edi, 48
585B3D80 8BCC mov ecx, esp
585B3D82 57 push edi
585B3D83 E8 75C721FF call 577D04FD
585B3D88 53 push ebx
585B3D89 E8 8BF4FFFF call 585B3219
585B3D8E 83C4 6C add esp, 6C
585B3D91 8D8D 88FEFFFF lea ecx, dword ptr [ebp-178]
585B3D97 E8 25C121FF call 577CFEC1
585B3D9C 6A 00 push 0
585B3D9E 6A 02 push 2
585B3DA0 FFB5 F4FEFFFF push dword ptr [ebp-10C] ; 修改这里,把push disposition_from_event_flags改成push 5
585B3DA0 ; FF B5 F4 FE FF FF -> 6A 05 90 90 90 90
585B3DA6 8D85 88FEFFFF lea eax, dword ptr [ebp-178]
585B3DAC 50 push eax
585B3DAD 57 push edi
585B3DAE 8D8D F8FEFFFF lea ecx, dword ptr [ebp-108]
585B3DB4 C785 F0FEFFFF 0>mov dword ptr [ebp-110], 1
585B3DBE E8 27972000 call 587BD4EA ; OpenURLParams::OpenURLParams( )
585B3DC3 8D8D 88FEFFFF lea ecx, dword ptr [ebp-178]
585B3DC9 E8 F6C521FF call 577D03C4
585B3DCE 8B4E 34 mov ecx, dword ptr [esi+34]
585B3DD1 8B01 mov eax, dword ptr [ecx]
585B3DD3 8D95 F8FEFFFF lea edx, dword ptr [ebp-108]
585B3DD9 52 push edx
585B3DDA FF50 04 call dword ptr [eax+4]
585B3DDD 8D8D F8FEFFFF lea ecx, dword ptr [ebp-108]
585B3DE3 E8 E0962000 call 587BD4C8
585B3DE8 EB 21 jmp short 585B3E0B
585B3DEA 50 push eax
585B3DEB 57 push edi
585B3DEC FF76 34 push dword ptr [esi+34]
585B3DEF 8D8E 08FFFFFF lea ecx, dword ptr [esi-F8]
585B3DF5 8B01 mov eax, dword ptr [ecx]
585B3DF7 53 push ebx
585B3DF8 FF50 10 call dword ptr [eax+10]
585B3DFB 8BC8 mov ecx, eax
585B3DFD E8 87844FFF call 57AAC289
585B3E02 50 push eax
585B3E03 E8 6D33EFFF call 584A7175
585B3E08 83C4 14 add esp, 14
585B3E0B 8D8E 08FFFFFF lea ecx, dword ptr [esi-F8]
585B3E11 8B01 mov eax, dword ptr [ecx]
585B3E13 FF90 9C010000 call dword ptr [eax+19C]
585B3E19 33C9 xor ecx, ecx
585B3E1B 84C0 test al, al
585B3E1D 0F95C1 setne cl
585B3E20 51 push ecx
585B3E21 E8 1B28EFFF call 584A6641
585B3E26 8D85 F4FEFFFF lea eax, dword ptr [ebp-10C]
585B3E2C 50 push eax
585B3E2D C785 F4FEFFFF D>mov dword ptr [ebp-10C], 591214D8 ; ASCII "ClickedBookmarkBarURLButton"
585B3E37 E8 DE3E41FF call 579C7D1A ; RecordAction( )
585B3E3C 59 pop ecx
585B3E3D 59 pop ecx
585B3E3E 8B4D FC mov ecx, dword ptr [ebp-4]
585B3E41 5F pop edi
585B3E42 5E pop esi
585B3E43 33CD xor ecx, ebp
585B3E45 5B pop ebx
585B3E46 E8 83021EFF call 577940CE
585B3E4B C9 leave
585B3E4C C2 0800 retn 8
58AE8F2B 55 push ebp ; MenuRunnerImpl::RunMenuAt( )
58AE8F2C 8BEC mov ebp, esp
58AE8F2E 8B09 mov ecx, dword ptr [ecx]
58AE8F30 5D pop ebp
58AE8F31 ^ E9 B2FEFFFF jmp 58AE8DE8
58AE8DE8 55 push ebp
58AE8DE9 8BEC mov ebp, esp
58AE8DEB 51 push ecx
58AE8DEC 56 push esi
58AE8DED 8BF1 mov esi, ecx
58AE8DEF 807E 2C 00 cmp byte ptr [esi+2C], 0
58AE8DF3 74 08 je short 58AE8DFD
58AE8DF5 33C0 xor eax, eax
58AE8DF7 40 inc eax
58AE8DF8 E9 F5000000 jmp 58AE8EF2
58AE8DFD 53 push ebx
58AE8DFE 57 push edi
58AE8DFF E8 362611FF call 57BFB43A
58AE8E04 8B5D 18 mov ebx, dword ptr [ebp+18]
58AE8E07 8BF8 mov edi, eax
58AE8E09 85FF test edi, edi
58AE8E0B 74 2A je short 58AE8E37
58AE8E0D F6C3 02 test bl, 2
58AE8E10 74 11 je short 58AE8E23
58AE8E12 807F 04 00 cmp byte ptr [edi+4], 0
58AE8E16 75 1F jnz short 58AE8E37
58AE8E18 6A 01 push 1
58AE8E1A 8BCF mov ecx, edi
58AE8E1C E8 3D5F0100 call 58AFED5E
58AE8E21 EB 12 jmp short 58AE8E35
58AE8E23 6A 01 push 1
58AE8E25 8BCF mov ecx, edi
58AE8E27 E8 325F0100 call 58AFED5E
58AE8E2C F6C3 04 test bl, 4
58AE8E2F 0F84 AB000000 je 58AE8EE0
58AE8E35 33FF xor edi, edi
58AE8E37 8BC3 mov eax, ebx
58AE8E39 C1E8 02 shr eax, 2
58AE8E3C 24 01 and al, 1
58AE8E3E C646 2C 01 mov byte ptr [esi+2C], 1
58AE8E42 8846 2E mov byte ptr [esi+2E], al
58AE8E45 F6C3 01 test bl, 1
58AE8E48 74 0A je short 58AE8E54
58AE8E4A 84C0 test al, al
58AE8E4C 75 06 jnz short 58AE8E54
58AE8E4E C645 18 01 mov byte ptr [ebp+18], 1
58AE8E52 EB 08 jmp short 58AE8E5C
58AE8E54 C645 18 00 mov byte ptr [ebp+18], 0
58AE8E58 84C0 test al, al
58AE8E5A 75 12 jnz short 58AE8E6E
58AE8E5C FF75 0C push dword ptr [ebp+C]
58AE8E5F 8BCE mov ecx, esi
58AE8E61 E8 5FFFFFFF call 58AE8DC5
58AE8E66 84C0 test al, al
58AE8E68 74 04 je short 58AE8E6E
58AE8E6A B0 01 mov al, 1
58AE8E6C EB 02 jmp short 58AE8E70
58AE8E6E 32C0 xor al, al
58AE8E70 8B4E 04 mov ecx, dword ptr [esi+4]
58AE8E73 50 push eax
58AE8E74 FF75 18 push dword ptr [ebp+18]
58AE8E77 E8 53FEFFFF call 58AE8CCF
58AE8E7C 8365 FC 00 and dword ptr [ebp-4], 0 ; 此变量是mouse_event_flags
58AE8E80 C646 34 00 mov byte ptr [esi+34], 0
58AE8E84 85FF test edi, edi
58AE8E86 75 2C jnz short 58AE8EB4
58AE8E88 68 08010000 push 108
58AE8E8D E8 C9D8CAFE call 5779675B
58AE8E92 59 pop ecx
58AE8E93 85C0 test eax, eax
58AE8E95 74 17 je short 58AE8EAE
58AE8E97 807E 2E 00 cmp byte ptr [esi+2E], 0
58AE8E9B 56 push esi
58AE8E9C 0F94C1 sete cl
58AE8E9F 0FB6C9 movzx ecx, cl
58AE8EA2 51 push ecx
58AE8EA3 8BC8 mov ecx, eax
58AE8EA5 E8 C8510100 call 58AFE072
58AE8EAA 8BF8 mov edi, eax
58AE8EAC EB 02 jmp short 58AE8EB0
58AE8EAE 33FF xor edi, edi
58AE8EB0 C646 34 01 mov byte ptr [esi+34], 1
58AE8EB4 8B46 04 mov eax, dword ptr [esi+4]
58AE8EB7 897E 30 mov dword ptr [esi+30], edi
58AE8EBA 89B8 9C000000 mov dword ptr [eax+9C], edi
58AE8EC0 8D45 FC lea eax, dword ptr [ebp-4] ; 这里是&mouse_event_flags
58AE8EC3 50 push eax
58AE8EC4 FF75 14 push dword ptr [ebp+14]
58AE8EC7 8BCF mov ecx, edi
58AE8EC9 FF75 10 push dword ptr [ebp+10]
58AE8ECC FF76 04 push dword ptr [esi+4]
58AE8ECF FF75 0C push dword ptr [ebp+C]
58AE8ED2 FF75 08 push dword ptr [ebp+8]
58AE8ED5 E8 6D680100 call 58AFF747
58AE8EDA 807E 2E 00 cmp byte ptr [esi+2E], 0
58AE8EDE 74 05 je short 58AE8EE5
58AE8EE0 33C0 xor eax, eax
58AE8EE2 40 inc eax
58AE8EE3 EB 0B jmp short 58AE8EF0
58AE8EE5 FF75 FC push dword ptr [ebp-4] ; 修改这里,push mouse_event_flags改成push 0x20
58AE8EE5 ; FF 75 FC -> 6A 20 90
58AE8EE8 8BCE mov ecx, esi
58AE8EEA 50 push eax
58AE8EEB E8 50FEFFFF call 58AE8D40 ; MenuDone( )
58AE8EF0 5F pop edi
58AE8EF1 5B pop ebx
58AE8EF2 5E pop esi
58AE8EF3 C9 leave
58AE8EF4 C2 1400 retn 14
if (disposition_from_event_flags == 2) {
disposition_from_event_flags = 5;
}
else if (mouse_event_flags == 0x10) {
mouse_event_flags = 0x20;
}
不过我把这些步骤省了,不判断了
对于以上汇编,我做了个补丁,仅供测试之用,放在附注中下载
----------------------------------------------------------------------------------------------------
附注:
对于本例子我做的个小补丁仅供测试,含Chrome.dll(6分):
http://download.csdn.net/detail/ucantseeme/4207421
我的Chrome代码是从这里下载的:http://chromium-browser-source.commondatastorage.googleapis.com/chromium_tarball.html
2012年04月02日