As mentioned in the comments, this wont solve the problem at hand - although I did notice different behaviour of the two buttons when running under a clean install of XP SP3.
You can clearly see that SetWindowSubclass is much neater/easier to use. It also has the advantage that you can both apply it many times with different WndProcs and selectively remove any of the WndProcs in the chain. The old method however doesn't really offer a way to subclass the control several times simultaneously - the documentation explains this if I remember correctly - I think there may also be an example or two in there somewhere too.
main.cpp
#define UNICODE 1
#define _WIN32_WINNT 0x0501
#define WINVER 0x0500
#include <windows.h>
#include <commctrl.h>
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
wchar_t szClassName[ ] = L"CodeBlocksWindowsApp";
HINSTANCE hInst;
ATOM myRegClass()
{
WNDCLASSEX wincl;
wincl.hInstance = hInst;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
return RegisterClassEx (&wincl);
}
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd;
MSG messages;
hInst = hThisInstance;
if (myRegClass() == NULL)
return -1;
hwnd = CreateWindow(szClassName, L"Code::Blocks Windows App", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
544, 375,
HWND_DESKTOP,NULL,hThisInstance,NULL);
ShowWindow (hwnd, nCmdShow);
while (GetMessage (&messages, NULL, 0, 0))
{
if (IsDialogMessage(hwnd, &messages) == 0)
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
return messages.wParam;
}
HWND addTip(HWND target, wchar_t *tipText)
{
HWND parentWnd = GetParent(target);
HWND hwndTip = CreateWindowEx( NULL, TOOLTIPS_CLASS, NULL,
WS_POPUP | TTS_ALWAYSTIP,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
parentWnd, NULL, hInst, NULL );
TOOLINFO toolInfo = { 0 };
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = parentWnd;
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
toolInfo.uId = (UINT_PTR)target;
toolInfo.lpszText = tipText;
SendMessage( hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo );
return hwndTip;
}
void onPaint(HWND hwnd, WPARAM wParam, LPARAM lParam, COLORREF col)
{
RECT rc;
PAINTSTRUCT ps;
HDC hdc;
if (wParam == NULL)
hdc = BeginPaint(hwnd, &ps);
else
hdc = (HDC)wParam;
GetClientRect(hwnd, &rc);
HBRUSH hbr = CreateSolidBrush(col);
FillRect(hdc,&rc,hbr);
DeleteObject(hbr);
int txtLen, oldMode;
wchar_t *wndTxt;
txtLen = GetWindowTextLength(hwnd);
wndTxt = new wchar_t[txtLen+2];
GetWindowText(hwnd, wndTxt, txtLen+1);
oldMode = SetBkMode(hdc, TRANSPARENT);
DrawText(hdc, wndTxt, -1, &rc, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
SetBkMode(hdc, oldMode);
delete wndTxt;
if (GetFocus() == hwnd)
{
RECT focusRect = rc;
focusRect.left += 4;
focusRect.top += 4;
focusRect.right -= 4;
focusRect.bottom -= 4;
DrawFocusRect(hdc, &focusRect);
}
if (wParam == NULL)
EndPaint(hwnd, &ps);
}
LRESULT CALLBACK Btn2SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
onPaint(hwnd, wParam, lParam,RGB(50,140,87));
return 0;
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK Btn1Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
onPaint(hwnd, wParam, lParam,RGB(87,140,50));
return 0;
}
WNDPROC oldProc;
oldProc = (WNDPROC)GetWindowLong(hwnd, GWL_USERDATA);
return CallWindowProc(oldProc, hwnd, uMsg, wParam, lParam);
}
LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
HWND hButton = CreateWindow( L"Button", L"test me!",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|WS_TABSTOP,50, 50, 75, 23, hWnd, (HMENU)8003, hInst, 0 );
addTip(hButton, L"test1");
long origProc;
origProc = GetWindowLong(hButton, GWL_WNDPROC);
SetWindowLong(hButton, GWL_USERDATA, origProc);
SetWindowLong(hButton, GWL_WNDPROC, (long)Btn1Proc);
HWND btn2 = CreateWindow(L"Button", L"btn2", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|WS_TABSTOP, 50, 85, 75, 23, hWnd, (HMENU)8004,hInst,0);
SetWindowSubclass(btn2,Btn2SubclassProc, 1, NULL);
addTip(btn2, L"test2");
}
return 0L;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}