[PATCH 0/1] MR10039: comctl32: Fix the bug when the cInitial is too large which lead to CreateDIBSection fails.
When I was porting a software from windows, I met a problem that the icons in the imagelist were not displaying correctly. In the Application, the correct icons are: {width=269 height=29} But when I run it under wine is like this: {width=271 height=29} When I disassable the application code I found that the Application calls ImageList_Create by given a very large cInitial, which is 0xc0c0c0. This will lead to CreateDIBSection fail. Then the source hbitmap is lost, only hMask is left and shown up on the screen. I use windbg to debug this application on windows, I found that after ImageList_Create is called on Winodws, there is a valid hbitmap handle generated. When ImageList_Add is called for 4 times, it changed and called Bitblt to copy the hbitmap already added. So I guess windows has the error handling for ImageList_Create. If CreateDIBSection failes due to the large image count, it reduced the image count. By observing the action in ImageList_Add, I think the reduced count is 1 (4x1). Then fix the cMaxImage to 1+1 which is same as ImageListImpl_Initialize to make the hbitmap expand. The example in the attachment can reproduce this bug. [imagelist.7z](/uploads/b5f7013fa9383c00bbbc38f82383ff1a/imagelist.7z) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10039
From: Kun Yang <yangkun@uniontech.com> Logs: When CreateDIBSection does not return a valid hbitmap, the source image is lost that only masked icon is shown in imagelist. Signed-off-by: Kun Yang <yangkun@uniontech.com> --- dlls/comctl32/imagelist.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index 93c502ec0bd..443078600e4 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c @@ -3088,6 +3088,15 @@ static HBITMAP ImageList_CreateImage(HDC hdc, HIMAGELIST himl, UINT count) } } hbmNewBitmap = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, 0, 0); + if(!hbmNewBitmap) + { + UINT newImageCount = 1; + //if CreateDIBSection failed, allocate for 1 image only. + bmi->bmiHeader.biHeight = newImageCount * himl->cy; + hbmNewBitmap = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, 0, 0); + //the max image count is set to 2, expand when exceeded. + himl->cMaxImage = newImageCount + 1; + } } else /*if (ilc == ILC_COLORDDB)*/ { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10039
This will need some tests. The easiest way probably is to check serialized value of the cMaxImage field. Maybe it simply has to be limited by some number. P.S. the value you mention sounds more like a color, so could be a unintentional mistake that happens to work on Windows. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10039#note_128941
Please add the tests to the test suites for Wine. You can see wine/dlls/comctl32/tests/imagelist.c for examples. And use /**/ for comments instead of //. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10039#note_128943
你需要把测试添加到Wine项目的测试里,比如wine/dlls/comctl32/tests/imagelist.c。这样才会被Gitlab CI运行。虽然你有一个测试程序,但是这样的测试需要人工交互运行。 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10039#note_128946
You can see https://gitlab.winehq.org/wine/wine/-/merge_requests/10037 for how to do it. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10039#note_128947
@zhiyi 我很抱歉我这个mr是在push到了我fork的工程的master分支上了,导致我现在无法更新mr,我是否只能重新再提一个mr? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10039#note_128950
On Fri Feb 6 09:35:08 2026 +0000, Kun Yang wrote:
@zhiyi 我很抱歉我这个mr是在push到了我fork的工程的master分支上了,导致我现在无法更新mr,我是否只能重新再提一个mr? 你可以继续push到你的fork的工程上的master分支,这样更新会自动同步到这个MR. 如果你想用另一个分支来更新该MR,那么你确实需要重新开启一个MR.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10039#note_128957
participants (4)
-
Kun Yang -
Kun Yang (@yangkun) -
Nikolay Sivov (@nsivov) -
Zhiyi Zhang (@zhiyi)