Click here to Skip to main content
15,789,698 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
There is a WM_SETREDRAW message in WinAPI which you can send to a window in order to suspend/resume drawing updates. It works fine, but as soon as i add visual styles from comctl32 v.6.0.0 to my program calling WM_SETREDRAW on a ListView control fails (GetLastError() returns 1400 after sending the message).
Here is the program:

#include <windows.h>
// manifest for supporting themes
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, char*, int)
    HWND lv = CreateWindow(L"SysListView32", 0, WS_VISIBLE, 0,0 ,111,111,0,0,hInst,0);
    SendMessage(lv, WM_SETREDRAW, false, 0); // After this call GetLastError() returns 1400

My question is - how do you properly use WM_SETREDRAW on a listview in application that uses styles?

What I have tried:

Searched the internet and tried to establish the source of the problem (which i found). Also i checked MSDN documentation for WS_SETREDRAW and Adding visual styles to your program and neither says about some restrictions when used together.
Updated 10-Jul-23 0:48am

See the Remarks section at WM_SETREDRAW message[^].
Share this answer
Avtem 9-Jul-23 13:08pm    
i've read again, there is no information about visual styles
Richard MacCutchan 9-Jul-23 14:02pm    
OK, well there two possibilities:
1. The call to CreateWindow fails so the window handle is invalid (Error code 1400).
2. The window has not enabled the WM_SETREDRAW message, as explained in the link I provided above.
You need to use the debugger to find out which it is.
Avtem 9-Jul-23 14:22pm    
1. After CreateWindow call Error code is always 0.
Error code 1400 is set after sending WM_SETREDRAW message *only* when visual styles are on. When they are off - Error code is 0 and WM_SETREDRAW suppresses window redraws
2. By *enabling* WM_SETREDRAW you mean SendMessage(lv, WM_SETREDRAW, false, 0);?
Richard MacCutchan 10-Jul-23 3:30am    
No, I mean read the Remarks section in the link I provided, especially the last paragraph that starts Windows 10 and later; Windows Server 2016 and later.
Avtem 10-Jul-23 4:54am    
Oh, that's what you meant. The target OS is Windows 7 x32/64 bit - sorry i should have mentioned that in the OP.
GetPropW(lv, L"SysSetRedraw") always returns 0.
i also noticed that WM_SETREDRAW never removes the WS_VISIBLE style as it should do.
Other control types lose WS_VISIBLE style after WM_SETREDRAW though.
Unfortunately i couldn't figure out how to use WM_SETREDRAW with ListView controls, but since MDSN describes us how it's implemented i decided to do what they do - remove or add WS_VISIBLE style from the window without invalidating its rectangle.
Here is the pseudo code:

// SendMessage(lv, WM_SETREDRAW, false, 0); // Instead of this
utils::deleteStyle(lv, WS_VISIBLE); // Use WinAPI code of your choice to remove WS_VISIBLE style
// Do something with the window
utils::addStyle(lv, WS_VISIBLE); // Add WS_VISIBLE back
RedrawWindow(lv, 0, 0, RDW_INVALIDATE | RDW_ALLCHILDREN); // Force redraw

Of course i don't know how Microsoft exactly implemented that, but the solution above seems to work similarly to WM_SETREDRAW.
Share this answer
Richard MacCutchan 10-Jul-23 9:34am    
I just tried this with a ListView window and it works exactly as specified in the documentation. Also GetLastError returns zero in both cases. So whatever you are doing in your code you must be doing something wrong that you have not shown us.
Avtem 10-Jul-23 9:38am    
i think it's maybe some problem with my environment, because the OP contains the faulty code in its entirety

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900