Click to See Complete Forum and Search --> : Removing frame of control (while Subclassing)


DaAvange
August 15th, 2007, 10:44 AM
Hello,
I don't know if the title is right, be here is what I did so far and what I'm tring to do.

I subclassing the common control progress bar class so I can change its appearance and it worked really well,


LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT lpPaintStruct;
switch(uMsg) {
case WM_PAINT: {
BeginPaint(hwnd, &lpPaintStruct);
DrawProgressBar(hwnd);
EndPaint(hwnd, &lpPaintStruct);
return TRUE;
}
default:
return CallWindowProc(OldWndProc, hwnd, uMsg, wParam, lParam);
}
return 0;
}


void DrawProgressBar(HWND hWnd) {
RECT WndRect;
GetWindowRect(hWnd, &WndRect);

int PhysWidth = WndRect.right - WndRect.left;
int PhysHeight = WndRect.bottom - WndRect.top;

UINT NewPerc = SendMessage(hWnd, PBM_GETPOS, 0, 0);
UINT MaxPerc = SendMessage(hWnd, PBM_GETRANGE, FALSE, NULL);

register UINT c;

HBITMAP hBackBmp;
HDC frontHDC;
HDC backHDC;
HDC TargetHDC;
DWORD dwLimit;

if (NewPerc > MaxPerc) NewPerc = MaxPerc;
if (MaxPerc != 100) {
if (NewPerc > 0) NewPerc = (int)(((float) NewPerc / (float) MaxPerc) * 100);
else NewPerc = 0;
}

TargetHDC = GetDC(hWnd);
hBackBmp = CreateCompatibleBitmap(TargetHDC, SliceWidth * 101, SliceHeight);
backHDC = CreateCompatibleDC(TargetHDC);
SelectObject(backHDC, hBackBmp);
frontHDC = CreateCompatibleDC(TargetHDC);

dwLimit = GdiSetBatchLimit((DWORD) 100);
for (c = 0; c <= 100; c++) {
if (c == 0) SelectObject(frontHDC, ((NewPerc > 0) ? hTubeColorLeft : hTubeEmptyLeft));
else if (c == 100) {
SelectObject(frontHDC, ((NewPerc == 100) ? hTubeColorRight : hTubeEmptyRight));
}
else {
if (c < NewPerc) SelectObject(frontHDC, hTubeColorFilled);
else if (c == NewPerc) SelectObject(frontHDC, hTubeColorFiller);
else SelectObject(frontHDC, hTubeEmptyMiddle);
}
BitBlt(backHDC, c *SliceWidth , 0, SliceWidth, SliceHeight, frontHDC, 0, 0, SRCCOPY);
}
StretchBlt(TargetHDC, 1, 1, PhysWidth, PhysHeight, backHDC, 0, 0, SliceWidth * 101, SliceHeight, SRCCOPY);
GdiFlush();
GdiSetBatchLimit(dwLimit);
ReleaseDC(hWnd, TargetHDC);
DeleteDC(frontHDC);
DeleteDC(backHDC);
}


It draws it, but there is a annoying rectangle frame of that control that allways stays there (and its not WS_BORDER) , here is the picture:
http://img186.imageshack.us/img186/9819/untitledrz8.jpg

ovidiucucu
August 15th, 2007, 04:12 PM
Remove also the WS_EX_STATICEDGE style.
Example:

LONG nExStyle = GetWindowLong(hWndProgress, GWL_EXSTYLE);
nExStyle &= ~WS_EX_STATICEDGE;
SetWindowLong(hWndProgress, GWL_EXSTYLE, nExStyle);

DaAvange
August 15th, 2007, 06:12 PM
Yey, it worked!
Thanks.

Here is the entire code if anyone is intrested:

//Subclassing "msctls_progress32" class
#pragma once
#include <windows.h>
#include <commctrl.h>

int SliceWidth = 10; // the width (in pixels) of the bitmap parts
int SliceHeight = 20; // the hight (in pixels) of the bitmap parts

HBITMAP hTubeEmptyLeft = NULL;
HBITMAP hTubeEmptyRight = NULL;
HBITMAP hTubeEmptyMiddle = NULL;
HBITMAP hTubeColorLeft = NULL;
HBITMAP hTubeColorRight = NULL;
HBITMAP hTubeColorFilled = NULL;
HBITMAP hTubeColorFiller = NULL;

WNDPROC OldWndProc = NULL;


void DrawProgressBar(HWND hWnd) {
RECT WndRect;
GetWindowRect(hWnd, &WndRect);

int PhysWidth = WndRect.right - WndRect.left - 7;
int PhysHeight = WndRect.bottom - WndRect.top;

UINT NewPerc = SendMessage(hWnd, PBM_GETPOS, 0, 0);
UINT MaxPerc = SendMessage(hWnd, PBM_GETRANGE, FALSE, NULL);

register UINT c;

HBITMAP hBackBmp;
HDC frontHDC;
HDC backHDC;
HDC TargetHDC;
DWORD dwLimit;

if (NewPerc > MaxPerc) NewPerc = MaxPerc;
if (MaxPerc != 100) {
if (NewPerc > 0) NewPerc = (int)(((float) NewPerc / (float) MaxPerc) * 100);
else NewPerc = 0;
}

TargetHDC = GetDC(hWnd);
hBackBmp = CreateCompatibleBitmap(TargetHDC, SliceWidth * 101, SliceHeight);
backHDC = CreateCompatibleDC(TargetHDC);
SelectObject(backHDC, hBackBmp);
frontHDC = CreateCompatibleDC(TargetHDC);

dwLimit = GdiSetBatchLimit((DWORD) 100);
for (c = 0; c <= 100; c++) {
if (c == 0) SelectObject(frontHDC, ((NewPerc > 0) ? hTubeColorLeft : hTubeEmptyLeft));
else if (c == 100) {
SelectObject(frontHDC, ((NewPerc == 100) ? hTubeColorRight : hTubeEmptyRight));
}
else {
if (c < NewPerc) SelectObject(frontHDC, hTubeColorFilled);
else if (c == NewPerc) SelectObject(frontHDC, hTubeColorFiller);
else SelectObject(frontHDC, hTubeEmptyMiddle);
}
BitBlt(backHDC, c *SliceWidth , 0, SliceWidth, SliceHeight, frontHDC, 0, 0, SRCCOPY);
}
StretchBlt(TargetHDC, 1, 1, PhysWidth, PhysHeight, backHDC, 0, 0, SliceWidth * 101, SliceHeight, SRCCOPY);
GdiFlush();
GdiSetBatchLimit(dwLimit);
ReleaseDC(hWnd, TargetHDC);
DeleteDC(frontHDC);
DeleteDC(backHDC);
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT lpPaintStruct;
switch(uMsg) {
case WM_CREATE: {
CallWindowProc(OldWndProc, hwnd, uMsg, wParam, lParam);
LONG nExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
nExStyle &= ~WS_EX_STATICEDGE;
SetWindowLong(hwnd, GWL_EXSTYLE, nExStyle);
return TRUE;
}
case WM_PAINT: {
BeginPaint(hwnd, &lpPaintStruct);
DrawProgressBar(hwnd);
EndPaint(hwnd, &lpPaintStruct);
return TRUE;
}
default:
return CallWindowProc(OldWndProc, hwnd, uMsg, wParam, lParam);
}
return 0;
}


bool InitProgressSubclass() {
HINSTANCE MyMoudle = GetModuleHandle(NULL);

hTubeEmptyLeft = (HBITMAP) LoadImage(MyMoudle, MAKEINTRESOURCE(TubeEmptyLeft), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
hTubeEmptyRight = (HBITMAP) LoadImage(MyMoudle, MAKEINTRESOURCE(TubeEmptyRight), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
hTubeEmptyMiddle = (HBITMAP) LoadImage(MyMoudle, MAKEINTRESOURCE(TubeEmptyMiddle), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
hTubeColorLeft = (HBITMAP) LoadImage(MyMoudle, MAKEINTRESOURCE(TubeBlueLeft), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
hTubeColorRight = (HBITMAP) LoadImage(MyMoudle, MAKEINTRESOURCE(TubeBlueRight), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
hTubeColorFilled = (HBITMAP) LoadImage(MyMoudle, MAKEINTRESOURCE(TubeBlueFilled), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
hTubeColorFiller = (HBITMAP) LoadImage(MyMoudle, MAKEINTRESOURCE(TubeBlueFiller), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);

HWND hwnd = CreateWindow("msctls_progress32", "", 0, 0, 0, 0, 0, NULL, NULL, MyMoudle, NULL);
if (hwnd == NULL) return false;
OldWndProc = (WNDPROC) SetClassLong(hwnd, GCL_WNDPROC, (LONG) WndProc);
DestroyWindow(hwnd);
return true;
}


To use it, the project is needed to include sevral images....
and to start it just call:


InitProgressSubclass();


And use the progressbar as normal :)