被实验的wine 来资源winehq原版10.0(32位)。
被实验的程序 Winhex(32位)
下载wine 并添加安装好编译环境(略)
config 和make即可 ,里面其他模块(如win32u)直接进去运行里面的make即可编译这个模块。
可以看到图标显示错误(底色是黑色)
很快就定位到下面这个函数(dlls/win32u/menu.c)
static void draw_menu_item( HWND hwnd, struct menu *menu, HWND owner, HDC hdc, struct menu_item *item, BOOL menu_bar, UINT odaction )
//找到这个函数中的下面这个位置 //不是系统菜单(不是顶级菜单) if (!menu_bar) { HBITMAP bm; INT y = rect.top + rect.bottom; BOOL checked = FALSE; UINT check_bitmap_width = get_system_metrics( SM_CXMENUCHECK ); UINT check_bitmap_height = get_system_metrics( SM_CYMENUCHECK ); /* Draw the check mark */ if (!(menu->dwStyle & MNS_NOCHECK)) { bm = (item->fState & MF_CHECKED) ? item->hCheckBit : item->hUnCheckBit; if (bm) /* we have a custom bitmap */ { BITMAP bm_info; HDC mem_hdc; TRACE("-------Icon HBITMAP Check: ID=0x%x, Handle=%p.\n", item->wID, bm); // 获取位图信息 // **新增:获取位图尺寸** if (!NtGdiExtGetObjectW( bm, sizeof(bm_info), &bm_info)) { TRACE("Attempting TransparentBlt for custom menu icon failed! (bm_info: 0x%08x).\n", (ULONG)&bm_info); } mem_hdc = NtGdiCreateCompatibleDC( hdc ); NtGdiSelectBitmap( mem_hdc, bm ); /* NtGdiBitBlt( hdc, rect.left, (y - check_bitmap_height) / 2, check_bitmap_width, check_bitmap_height, mem_hdc, 0, 0, SRCCOPY, 0, 0 ); */ // --- 替换开始 --- //COLORREF transparent_color = 0x000000; // 假定黑色为透明色 TRACE("Attempting TransparentBlt for custom menu icon (ColorKey: 0x%06x).\n", (ULONG)0x000000); if (!NtGdiTransparentBlt( hdc, rect.left, (y - bm_info.bmHeight) / 2, // 使用位图实际高度进行居中 bm_info.bmWidth, bm_info.bmHeight, mem_hdc, 0, 0, bm_info.bmWidth, bm_info.bmHeight, 0x000000)) { // Fallback to original BitBlt (如果 TransparentBlt 失败) TRACE("NtGdiTransparentBlt failed, falling back to SRCCOPY.\n"); NtGdiBitBlt( hdc, rect.left, (y - check_bitmap_height) / 2, check_bitmap_width, check_bitmap_height, mem_hdc, 0, 0, SRCCOPY, 0, 0 ); } else { TRACE("NtGdiTransparentBlt succeeded.\n"); } // --- 替换结束 --- NtGdiDeleteObjectApp( mem_hdc ); checked = TRUE; } else if (item->fState & MF_CHECKED) /* standard bitmaps */ { RECT r; HBITMAP bm = NtGdiCreateBitmap( check_bitmap_width, check_bitmap_height, 1, 1, NULL ); HDC mem_hdc = NtGdiCreateCompatibleDC( hdc ); NtGdiSelectBitmap( mem_hdc, bm ); SetRect( &r, 0, 0, check_bitmap_width, check_bitmap_height); draw_frame_menu( mem_hdc, &r, (item->fType & MFT_RADIOCHECK) ? DFCS_MENUBULLET : DFCS_MENUCHECK ); NtGdiBitBlt( hdc, rect.left, (y - r.bottom) / 2, r.right, r.bottom, mem_hdc, 0, 0, SRCCOPY, 0, 0 ); NtGdiDeleteObjectApp( mem_hdc ); NtGdiDeleteObjectApp( bm ); checked = TRUE; } } if (item->hbmpItem && !(checked && (menu->dwStyle & MNS_CHECKORBMP))) { POINT origorg; /* some applications make this assumption on the DC's origin */ set_viewport_org( hdc, rect.left, rect.top, &origorg ); draw_bitmap_item( hwnd, hdc, item, &bmprc, menu, owner, odaction ); set_viewport_org( hdc, origorg.x, origorg.y, NULL ); } /* Draw the popup-menu arrow */ if (item->fType & MF_POPUP) draw_popup_arrow( hdc, rect, arrow_width, arrow_height); rect.left += 4; if (!(menu->dwStyle & MNS_NOCHECK)) rect.left += check_bitmap_width; rect.right -= arrow_width; }
cd /wine/dlls/win32u# make
!完美
记录下第一次尝试修wine。
欢迎大家给我一些其他简单wine的小问题以便继续写文章。
分享从wine小白到精通的过程。
No replies yet
Featured Collection
Popular Events
被实验的wine 来资源winehq原版10.0(32位)。
被实验的程序 Winhex(32位)
实验开始
1.git clone wine
下载wine 并添加安装好编译环境(略)
2. 解决好中文问题
3.编译以下新下载的wine
config 和make即可 ,里面其他模块(如win32u)直接进去运行里面的make即可编译这个模块。
4.问题展示
尝试解决问题
通过winedbg log下菜单打开时调用的函数
很快就定位到下面这个函数(dlls/win32u/menu.c)
重新编译dll/win32u这个模块
结果展示
!完美
记录下第一次尝试修wine。
欢迎大家给我一些其他简单wine的小问题以便继续写文章。
分享从wine小白到精通的过程。