|
Hello,
Stuck on a Microsoft drawing problem: The brush I'm using to draw text is being ignored, and SelectObject () returns NULL when I try to select it into a device context:
HFONT hFont = CreateFontIndirect(& logFont);
HFONT oldFont = (HFONT) SelectObject (hDc, hFont);
HBRUSH oldBrush = (HBRUSH) SelectObject (hDc, hbrush);
TextOut (hDc, 0, 0, fontName, wcslen (fontName));
The brush comes from the nativeBrush member of a .NET System.Drawing.Brush, which works correctly both before and after this.
I've tried using DrawText () instead, with the same result. Can anyone point out what I'm doing wrong? Thanks!
"Microsoft -- Adding unnecessary complexity to your work since 1987!"
|
|
|
|
|
Brushes are used to fill the interior of filled shapes. They are not used to draw text.
TextOut() and DrawText() use the text and background colors currently selected by the device context. These can be set using SetTextColor() and SetBkColor() .
SelectObject() returns the object that is going to be replaced. This may be NULL if there is actually no such object selected into the device context. It is not an error condition. The return value is usally used to restore the old state after drawing has been done.
|
|
|
|
|
Hmm... I'm using the same brush to draw text in the .NET half of the application. These are complex patterns (linear gradient and hatch brushes), and the text correctly appears with these textures in GDI+/.NET.
I'm using GDI (no plus) in this part because GDI+ doesn't support OpenType or PostScript fonts (only TrueType).
So how can these patterns be used in text under GDI?
"Microsoft -- Adding unnecessary complexity to your work since 1987!"
|
|
|
|
|
I'm sorry, I don't think that there is a solution with GDI.
|
|
|
|
|
Thanks for the input!
"Microsoft -- Adding unnecessary complexity to your work since 1987!"
|
|
|
|
|
Yeah, it shouldn't be a problem to do what you're asking for.
You need to make use of _both_ TextOut and Paths.
Basically, the process goes like this (sorry code is in a PDF ebook that prevents copy and paste)
1. Create your font
2. Select it into your hdc
3. Call BeginPath(hdc)
4. Call TextOut
5. Call EndPath
6. Use StrokePath for the outline, FillPath for the interior.
7. Select the old font back into the hdc
8. delete your font from #1
Ah! found a CHM version of the same book. Here's the code given there:
(I'll leave it as, unedited, for completeness)
void PaintRoutine (HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
static TCHAR szString [] = TEXT ("Filling") ;
HFONT hFont ;
SIZE size ;
hFont = EzCreateFont (hdc, TEXT ("Times New Roman"), 1440, 0, 0, TRUE) ;
SelectObject (hdc, hFont) ;
SetBkMode (hdc, TRANSPARENT) ;
GetTextExtentPoint32 (hdc, szString, lstrlen (szString), &size) ;
BeginPath (hdc) ;
TextOut (hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2,
szString, lstrlen (szString)) ;
EndPath (hdc) ;
SelectObject (hdc, CreateHatchBrush (HS_DIAGCROSS, RGB (255, 0, 0))) ;
SetBkColor (hdc, RGB (0, 0, 255)) ;
SetBkMode (hdc, OPAQUE) ;
StrokeAndFillPath (hdc) ;
DeleteObject (SelectObject (hdc, GetStockObject (WHITE_BRUSH))) ;
SelectObject (hdc, GetStockObject (SYSTEM_FONT)) ;
DeleteObject (hFont) ;
}
Make it work. Then do it better - Andrei Straut
|
|
|
|
|
Wow, that's some fancy coding! People elsewhere are saying it's impossible. Thanks enhzflep!
"Microsoft -- Adding unnecessary complexity to your work since 1987!"
|
|
|
|
|
You're welcome
Yeah, Charles Pretzold always was a smart cookie.
I'm so glad that I remembered having read a section in his books about the topic.
Make it work. Then do it better - Andrei Straut
|
|
|
|
|
Hi enhzflep,
I incorporated code from your example into my function, and it works with the CreateHatchBrush call to create a new brush.
Unfortunately, when I substitute my already-created brush, it doesn't work; I just get solid white filling the text outlines.
I've verified the brush handle is the same as the nativeBrush member of my .NET Brush, which draws correctly both before and after. Can you see anything I'm doing wrong?
DLLEXPORT void drawWithGdiFont (HBITMAP hBitmap, HBRUSH hbrush, LPCWSTR fontName,
LPCWSTR text, int sizeToUse, bool bold, bool italic, int br, int bg, int bb)
{
HDC hDc = CreateCompatibleDC (NULL);
HGDIOBJ oldObj = SelectObject (hDc, hBitmap);
SIZE size ;
LOGFONT logFont;
::ZeroMemory(& logFont, sizeof(LOGFONT));
wcscpy ((&logFont)->lfFaceName, fontName);
logFont.lfHeight = sizeToUse;
if (bold)
logFont.lfWeight = 800;
else
logFont.lfWeight = 500;
logFont.lfItalic = italic;
HFONT hFont = CreateFontIndirect(& logFont);
HFONT oldFont = (HFONT) SelectObject (hDc, hFont);
SetBkMode (hDc, TRANSPARENT) ;
BeginPath (hDc) ;
TextOut (hDc, 0, 0, fontName, wcslen (fontName));
EndPath (hDc) ;
HBRUSH oldBrush = (HBRUSH) SelectObject (hDc, hbrush);
SetBkColor (hDc, RGB (br, bg, bb));
SetBkMode (hDc, OPAQUE) ;
StrokeAndFillPath (hDc) ;
DeleteObject (SelectObject (hDc, oldFont));
SelectObject (hDc, oldBrush);
DeleteObject (hDc);
}
Also, it seems like the background color here is the second color of the hatch pattern. But how do I set the color between the letters (which is also called the "background color"?)
Thanks!
Alan
"Microsoft -- Adding unnecessary complexity to your work since 1987!"
|
|
|
|
|
Hi,
I am developing a file download utility using MFC. The application downloads a simple file over the internet. During download, is there a way to detect if the network connectivity is lost? Because the CHttpFile->Read function doesn't exit if the connection isn't lost.
Sunil
|
|
|
|
|
sunilkpv wrote: Because the CHttpFile->Read function doesn't exit if the connection isn't lost. Are you saying that it should exit if the connection is not lost?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
Sorry. That was a typo. What you said is right. I found a solution for this by setting a timeout using the CInternetSession class.
However I have ended up with another similar problem. I am reading a file over the network drive using CFIle class. Now if the network drive access is lost (due to any reason) can we get to know this. The read() function continues without breaking. How can this be solved?? Please help...
Sunil
|
|
|
|
|
I give some code :
BOOL CYourDoc::DownloadFile(CString sAddress, CString& sResult)
{
CString sTemp;
BOOL bRet = FALSE;
CInternetSession ISession;
CInternetFile* pIFile = NULL;
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
try
{
pIFile = (CInternetFile*)ISession.OpenURL(sAddress);
while(pIFile->ReadString(sTemp))sResult += sTemp;
bRet = TRUE;
}
catch(CException* pException)
{
pException->GetErrorMessage(sTemp.GetBuffer(255),255);
sTemp.ReleaseBuffer();
pException->Delete();
pFrame->SetMessageText(sTemp);
}
if(pIFile)
{
pIFile->Close();
delete pIFile;
}
ISession.Close();
return bRet;
}
I this code, when something happened, throw an exception, there you can do whatever you want ... I hope this help you ...
|
|
|
|
|
sunilkpv wrote: The read() function continues without breaking. What is it continuing doing? Reading what? What does your read loop look like?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
Hello Friends
I am creating a application in which I am saving a image as bmp using BITMAPINFOHEADER.
But this structure' height/Width variable is saving image size in Pixels and that i coming fine If i check in Photoshop. But Its Document size[height and width in inches] is not coming fine.As its resolution is by default 72.
And then this Document size is not matching up with mine application ht/width in inches.
Is there any other member varible of BITMAPINFOHEADER structure where I can directly set image size[ht/wd] in inches?
Or any other way So that i can get actual size of image If i open it in some image viewer?
Regards
Yogesh Sikri
|
|
|
|
|
Check out the biXPelsPerMeter and biYPelsPerMeter members that are in pixels/meter units: BITMAPINFOHEADER[^].
|
|
|
|
|
Now,I setted it value to 0x0ec4. and Image size in Inches are coming fine when I look in photoshop. Thanks A Lot.
But,its coming fine for bmp and tiff.For tga ,its coming default res 72.
Any Idea?
Regards
Yogesh
|
|
|
|
|
as far as i know, the TGA format does not provide a method of storing DPI info.
|
|
|
|
|
Hi
What is the best way to create an edit box (derived from CEdit) that can draw a red line under wrong words for example. and then user can right click on it and correct it from a sugested menu list. (Like what visual assist does in Visual Studio)
Doing it insdie OnPaint() is not easy because we must take care of single or multi line, and maybe some other thing.
An example or project will help a lot.
Regards
Hadi
www.logicsims.ir
|
|
|
|
|
Have you think to use CRichEditCtrl instead of CEdit ?
|
|
|
|
|
|
Sorry you all for bothering on Sunday:
I'm new using C++ and I need to simulate a Social network, but I'm having troubles doing a "member": this
is the code is very simple:
I hava a header called "structs.h"
struct Miembro{
int id;
int activo;
int pass;
Miembro(int a, int b, int c)
{
id = a;
activo = b;
pass = c;
}
};
#include <cstdlib>
#include <iostream>
#include <string>
#include "structs.h"
using namespace std;
int main(void)
{
cout<< "hola";
string nombre;
nombre = "Jorge";
cout <<" "<< nombre << endl;
Miembro memb = new Miembro(1, 1, 123);
}
F:\main.cpp In function 'int main()':
17 37 F:\main.cpp [Error] conversion from 'Miembro*' to non-scalar type 'Miembro' requested
F:\Makefile.win [Error] [main.o] Error 1 (if this is the only error: please check your library includes)
jorgmen
|
|
|
|
|
Because you're creating a new Miembro in this way, all you get back is a pointer to it. You then try to assign this pointer to an object of type Miembro.
Just change it to this:
Miembro *memb = new Miembro(1,1,123);
Make it work. Then do it better - Andrei Straut
|
|
|
|
|
OR, you can just say
Miembro memb(1, 1, 123);
and this will allocate the memb object on the stack. I think this is the recommended way to allocate small objects whenver possible. Objects allocated on the stack are deleted automatically for you when they run out of scope (usually at the end of your function or if-block or whatever). If you allocate an object from the heap then you get a pointer to the heap and you must delete that object via its pointer when you done with it using the delete keyword. By forgetting to delete heap objects your program might continuously 'eat' the memory until you exit the program (this memory waste is called 'memory leak').
|
|
|
|
|
Thaks for your replays:
now i have a new q?
struct Miembro{
int id;
int activo;
int pass;
Miembro(int a, int b, int c)
{
id = a;
activo = b;
pass = c;
}
};
struct NodoMiembro{
NodoMiembro * nextmiem;
NodoMiembro * prevmiem;
Miembro persona;
NodoMiembro(Miembro nuevo){
nextmiem = prevmiem = NULL;
persona = nuevo;
}
};
struct ListaMiembros{
NodoMiembro * lastmember;
NodoMiembro * firstmember;
ListaMiembros(){
lastmember = firstmember = NULL;
}
I can't compile this, I'm having headache because of c++: it says:
4 0 F:\main.cpp In file included from main.cpp
F:\structs.h In constructor 'NodoMiembro::NodoMiembro(Miembro)':
31 27 F:\structs.h [Error] no matching function for call to 'Miembro::Miembro()'
31 27 F:\structs.h [Error] candidates are:
17 1 F:\structs.h Miembro::Miembro(int, int, int)
17 1 F:\structs.h candidate expects 3 arguments, 0 provided
12 8 F:\structs.h Miembro::Miembro(const Miembro&)
12 8 F:\structs.h candidate expects 1 argument, 0 provided
F:\structs.h At global scope:
WHY NodoMiembro can't have a "Miembro xxx" as parameter in the constructor???
|
|
|
|
|