PDA

Click to See Complete Forum and Search --> : Problem with Deleting the GDI object


abdul
Jul 28th, 2001, 11:34 PM
I want to create my own pen and brush, draw an ellipse, and then delete the brush and pen.

The problem is that when I run my program, the font size of my clock in the system tray, and font size of the windows shows in the task bar also changes. Even when I end my program, it still remains the same until I restart my system. Here is a little hint of what I am doing:


HPEN hpen;
HBRUSH hbrush;
hpen = CreatePen(PS_SOLID, 1, RGB(255,0,0));
hbrush = CreateSolidBrush(RGB(0,255,255));

SelectObject(memhdc, hpen);
SelectObject(memhdc, hbrush);

Ellipse(memhdc, 0,0, 20,20);

DeleteObject(hbrush);
DeleteObject(hpen);



Do you know why it's effecting my whole system?
If you want the full source code then please reply!

parksie
Jul 29th, 2001, 06:35 AM
HBRUSH hOldBr = (HBRUSH)SelectObject(memhdc, hbrush);
HPEN hOldPen = (HPEN)SelectObject(memhdc, hpen);

Ellipse(memhdc, 0,0, 20,20);

SelectObject(memhdc, hOldBr);
SelectObject(memhdc, hOldPen);

DeleteObject(hbrush);
DeleteObject(hpen);You need to tidy the DC up first.

abdul
Jul 29th, 2001, 09:34 AM
But it is not drawing anything in colour. The "memhdc" is a memory hdc and I transfered a bitmap onto it to draw something on it. But when I dont draw anything, it is filled with just 2 types of colours - white and black, right?
How can erase the background and draw with the colours on it - I also want to draw text with different colours.

I know there is an API call called "SetDCPenColor" in windows 2000 but its not available in windows 98 or lower


Please dont ignore that!

parksie
Jul 29th, 2001, 10:08 AM
It doesn't matter. Bizarre things happen (as documented in MSDN) if you delete a GDI object without removing it from the DC. If you have a memory DC why not set it up when your program loads? That way you won't need SelectObject every time WM_PAINT arrives (speed things up a bit).

abdul
Jul 29th, 2001, 11:14 AM
Why can't I make a function to make bitmap with the text in it. As I said above, I can't really change the colour in the memory DC and I cannot delete the background from that DC. I want to work with that as I do do with my windows's DC. If you want the whole source code then here it is:



#include <windows.h>
#include <wingdi.h>
#include "resource.h"

static char g_szClassName[] = "MyWindowClass";
static HINSTANCE hinst = NULL;
#define ID_FONT1 2
//Function to stretch the bitmap for our menus
HBITMAP StretchBitmap(HBITMAP hbitmap);
//Function to create you own bitmap any type of font

HBITMAP CreateFontBitmap(char *sztext,int fontwidth,int fontheight,char *fontface,
BOOL fontbold, BOOL fontitalic, BOOL fontunderline,
BOOL fontstrikethrough, COLORREF fontcolour);
//Public handle of our window
HWND hwnd;

//Public variables to use in our menus :

HMENU hmenu, hmenupopup;
HBITMAP hfilebmp, heditbmp;


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{



WNDCLASSEX WndClass;
MSG Msg;

hinst = hInstance;

WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hinst;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = g_szClassName;
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&WndClass))
{
MessageBox(0, "Window Registration Failed! :(", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}


//Create a Menu with first "File" Menu Bar

hmenu = CreateMenu();

//Loads the bitmaps from the resource
hfilebmp = StretchBitmap(LoadBitmap(hinst, MAKEINTRESOURCE(FILEBMP)));
heditbmp = StretchBitmap(LoadBitmap(hinst, MAKEINTRESOURCE(EDITBMP)));
/*Loads the whole "File" Menubar and sets it as a popup menu
for our main menu*/
hmenupopup = LoadMenu(hinst, MAKEINTRESOURCE(FILEMENU));
AppendMenu(hmenu, MF_BITMAP| MF_POPUP, (int) hmenupopup, (PSTR)(LONG) hfilebmp);
/*Loads the whole "Edit" Menubar and sets it as a popup menu
for our main menu*/
hmenupopup = LoadMenu(hinst, MAKEINTRESOURCE(EDITMENU));
AppendMenu(hmenu, MF_BITMAP| MF_POPUP, (int) hmenupopup, (PSTR)(LONG) heditbmp);

hmenupopup = CreateMenu();

AppendMenu(hmenupopup, MF_BITMAP, ID_FONT1, (PSTR)(LONG) CreateFontBitmap("The Text",52,152,"Verdana", FALSE,FALSE,FALSE,FALSE, RGB(255,0,0)));
AppendMenu(hmenu, MF_POPUP | MF_STRING,(int)hmenupopup,"DF");


hwnd = CreateWindowEx(
NULL,
g_szClassName,
"Coloured Shapes Generator",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 320, 240,
NULL, hmenu, hinst, NULL);

if(hwnd == NULL)
{
MessageBox(0, "Window Creation Failed! :(", "Error!",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}


ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);


while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}

//Deletes the bitmaps to free the "Resources"
DeleteObject(heditbmp);
DeleteObject(hfilebmp);

return Msg.wParam;
}






LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{

switch(Message)
{

case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
DeleteObject(hmenu);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wparam, lparam);
}
return 0;
}



//Function to stretch the bitmap so that it has a minimum of viewable
// size

HBITMAP StretchBitmap(HBITMAP hbitmap)
{
HBITMAP ReturnBitmap;
BITMAP bm1, bm2;
HDC memhdc1, memhdc2, hdc;
TEXTMETRIC tm;

hdc = CreateIC("DISPLAY",NULL,NULL,NULL);

GetTextMetrics(hdc, &tm);

memhdc1 = CreateCompatibleDC(hdc);
memhdc2 = CreateCompatibleDC(hdc);

DeleteDC(hdc);

GetObject(hbitmap, sizeof(bm1), (LPSTR)&bm1);

bm2 = bm1;

bm2.bmHeight = (tm.tmHeight * bm2.bmHeight) / 8;
bm2.bmWidth = (tm.tmAveCharWidth * bm2.bmWidth) / 4;
bm2.bmWidthBytes = ((bm2.bmWidth + 15) / 16) * 2;

ReturnBitmap = CreateBitmapIndirect(&bm2);

SelectObject(memhdc1, hbitmap);
SelectObject(memhdc2, ReturnBitmap);

StretchBlt(memhdc2, 0,0,bm2.bmWidth, bm2.bmHeight,
memhdc1, 0,0, bm1.bmWidth, bm1.bmHeight, SRCCOPY);

DeleteDC(memhdc1);
DeleteDC(memhdc2);

DeleteObject(hbitmap);

return ReturnBitmap;

}

//Function to create you own bitmap any type of font

HBITMAP CreateFontBitmap(char *sztext, int fontwidth,int fontheight,char *fontface,
BOOL fontbold, BOOL fontitalic, BOOL fontunderline,
BOOL fontstrikethrough, COLORREF fontcolour)
{


HFONT hfont; // Handle to our font
SIZE size; //Holds the size of the string to print
TEXTMETRIC tm; //It is used get get some info about the DISPLAY text
HBITMAP ReturnBitmap; //Bitmap where we print our text
static LOGFONT lf; // Holds all the properties for our font
HDC memhdc, hdc; //The memoryDC and DISPLAY DC
HBRUSH hbrush;
HPEN hpen;
hdc = CreateIC("DISPLAY", NULL,NULL,NULL);
GetTextMetrics(hdc, &tm);
memhdc = CreateCompatibleDC(hdc);
//Now, we set the properties of our font. EG: size, face


fontheight == -1 ? lf.lfHeight = tm.tmHeight :
lf.lfHeight = fontheight; //The height of font

fontwidth == -1 ? lf.lfWidth = tm.tmAveCharWidth :
lf.lfWidth = fontwidth;//the width of font

//Is the text Italic?
fontitalic ? lf.lfItalic = TRUE : lf.lfItalic = FALSE;
//Is the text Bold?
fontbold ? lf.lfWeight = 800 : lf.lfWeight = 0;
//Is the text Underlined?
fontunderline ? lf.lfUnderline = TRUE : lf.lfUnderline = FALSE;
// Is the text Striked Out?
fontstrikethrough ? lf.lfStrikeOut = TRUE : lf.lfUnderline = FALSE;
//Copies the face of the font into the LOGFONT
strcpy((char*)lf.lfFaceName, fontface);

//Create the font based on the LOGFONT and returns a handle to it
hfont = (HFONT) SelectObject(memhdc, CreateFontIndirect(&lf));
//Gets the x and y coordinates of the text so that our bitmap is the same
// size as the text is
GetTextExtentPoint(memhdc, sztext, strlen(sztext), &size);
//Create a bitmap
ReturnBitmap = CreateBitmap(size.cx + 30, size.cy, 1,1, NULL);
//select the bitmap into the memory so that we can draw on it later
SelectObject(memhdc, ReturnBitmap);


//Draws the text onto the memory DC
/*
NOTE: When we draw onto the memory DC, we are actually drawing on
the bitmap. So whatever we do to the memory DC, it is done to
the bitmap
*/
hbrush = CreateSolidBrush(RGB(0,255,0));
hpen = CreatePen(PS_SOLID, 2, RGB(0,0,255));
HPEN holdpen = (HPEN)SelectObject(memhdc, hpen);
HBRUSH holdbrush = (HBRUSH)SelectObject(memhdc, hbrush);

Ellipse(memhdc, 0,0,30,size.cy);
TextOut(memhdc, 31,0, sztext, strlen(sztext));
SelectObject(memhdc, holdpen);
SelectObject(memhdc, holdbrush);
//Delete the handle to the font to free up the resources
DeleteObject(SelectObject(memhdc, hfont));
//Delete the memory DC to free up the resources
DeleteDC(memhdc);
//Delete the DISPLAY DC to free up the resources
DeleteDC(hdc);
//Return the actuall bitmap where we "drew" the text
return ReturnBitmap;

}