|
charlieg wrote: "use boost", which I feel is an indictment of C++ I rather think it is, "Oh, C++ string handling looks difficult, I'll find a different library". Yes, there is a learning curve but that is true of just about everything. You can probably guess that I have never used boost.
|
|
|
|
|
|
Max - lol, I thought this was going to be some stand up comedy regarding formatting! I'll be sure to watch it. Good post.
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
charlieg wrote: why is it so elephanting difficult to format a string into a buffer in standard C++?
What does that mean exactly? Both 'format' and in general why would you think that something would make it easy.
As I recall as to what I think you are referring in the cases in the past if I had a specific fixed need to put/get values into a buffer then I just wrote a class that did it appropriately. It would have get/set methods that would do the correct thing for the buffer.
Then there were a couple of management methods that set the buffer up, extracted it, etc.
Similar but simpler than the way XML/Json libraries work. And long ago I created at least one implementation that did things similar too those with multiple types and I did it in C++.
|
|
|
|
|
For example - suppose I want to format a log message. Beloved printf/sprintf:
sprintf(&buf[0], "Now is the time (%s) for all good %s blah blah.\r\n", GetTime(), "men");
I could add other items to the log message, say hex values, floating point with fixed # of decimal, etc. Why would you write a class for doing something like this? It's admittedly adhoc.
I'm trying to do something like this in C++, and I just don't see it. As I said, most of the hits from google are "use boost::format". I confess I just may have missed the obvious....
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
charlieg wrote: For example - suppose I want to format a log message. Beloved printf/sprintf:
sprintf(&buf[0], "Now is the time (%s) for all good %s blah blah.\r\n", GetTime(), "men");
First I wouldn't roll my own log, but that gets back to your point of not using a library.
So if no library then I would write my own log api, and it would include a varargs log methods (one for each filter type.) And I would just implement a standard varargs method to do the write.
I have done exactly that at least twice before standard log libraries existed.
charlieg wrote: Why would you write a class for doing something like this?
The examples in the past, to which I thought you might have been referring were in reference to populated a piece of binary data, for message protocols, which must have a very specific format. For example (2 byte positive int, 4 char identifier, 20 char text)
|
|
|
|
|
Quote: sprintf(&buf[0], "Now is the time (%s) for all good %s blah blah.\r\n", GetTime(), "men"); That would be
ostringstream oss;
oss << "Now is the time (" << GetTime() << ") for all good " << "men" << " blah blah." << endl;
string buf = oss.str();
|
|
|
|
|
Following up on this, I'll have to dig into that. That approach looks simple enough. Of course, the GetTime was a make believe function. Funny, I would think that I would have seen something like this under "Formatting Text in C++" or what have you. I'll dig for more examples.
Thanks
Charlie Gilley
<italic>Stuck in a dysfunctional matrix from which I must escape...
"Where liberty dwells, there is my country." B. Franklin, 1783
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
|
|
|
|
|
|
I still use snprintf and its unicode counterpart a lot along with the variable argument versions. They work just find and are reasonably safe for my uses.
|
|
|
|
|
I have a OWNERDRAW static label which is surrounded by other static labels
For some reason the DrawItem gets called repeatedly unit a stack exception occurs
I have tried setting the WS_CLIPCHILDREN and WS_CLIPSIBLINGS on The parent Dialog and
neighboring child controls but it doesn't seem to help
any suggestions welcome
|
|
|
|
|
ForNow wrote:
For some reason the DrawItem gets called repeatedly unit a stack exception occurs
That indicates that your DrawItem implementation might be called recursive (probably not directly but by calling a function that results in a redraw). So check your code for such calls. A drawing function should only draw the control itself and do nothing else like changing properties of the control. If you for example change the selection within the drawing function, that would trigger another redraw.
|
|
|
|
|
It was SetWindowText that was calling the DrawItem, I put it outside the DrawItem method
However the Text isn't being displayed at all.
Would you have any suggestion on how to set the Text in CStatic while using the DrawItem
to change the font text color and background
Thanks
|
|
|
|
|
SetWindowText() sets the text and initiates drawing which must be implemented in your DrawItem function!
Example (copied & pasted, unchecked, unthemed classic method):
void CMyStatic::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct->CtlType == ODT_STATIC);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
ASSERT(pDC != NULL);
pDC->FillSolidRect(&lpDrawItemStruct->rcItem, m_clrBkGnd);
CString str;
GetWindowText(str);
if (!str.IsEmpty())
{
UINT nFormat = m_nFormat;
DWORD dwStyle = GetStyle();
if (dwStyle & SS_NOPREFIX)
nFormat |= DT_NOPREFIX;
if ((dwStyle & SS_CENTERIMAGE) && str.Find(_T('\n')) < 0)
{
nFormat &= ~DT_WORDBREAK;
nFormat |= DT_VCENTER | DT_SINGLELINE;
}
if (dwStyle & SS_ELLIPSISMASK)
{
nFormat &= ~DT_EXPANDTABS;
switch (dwStyle & SS_ELLIPSISMASK)
{
case SS_ENDELLIPSIS :
nFormat |= DT_END_ELLIPSIS | DT_MODIFYSTRING; break;
case SS_PATHELLIPSIS :
nFormat |= DT_PATH_ELLIPSIS | DT_MODIFYSTRING; break;
case SS_WORDELLIPSIS :
nFormat |= DT_WORD_ELLIPSIS; break;
}
}
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(bDisabled ? ::GetSysColor(COLOR_GRAYTEXT) : m_clrText);
LPTSTR lpszText = str.GetBuffer();
pDC->DrawText(lpszText, -1, &lpDrawItemStruct->rcItem, nFormat);
str.ReleaseBuffer();
}
}
|
|
|
|
|
Thanks so much so anything written out to the control in DrawItem
Must be in the guise of a device context e.g DrawText or TextOut
Thanks again
|
|
|
|
|
Thanks
Code works great
However when I inserted the following code to set a font for the text everything get messed up
CFont l_font;
LOGFONT lf;
lf.lfHeight = 12;
lf.lfWeight = 700;
strcpy(lf.lfFaceName, "Arial");
l_font.CreateFontIndirect(&lf);
CFont* l_old_font = pDC->SelectObject(&l_font);
as you can see from create the text show fit
abendlabel->Create(_T("Abend Label"),WS_CHILD | SS_OWNERDRAW | WS_VISIBLE | WS_CLIPSIBLINGS, CRect(138, 14, 205, 31), this, IDC_ABEND_LABEL);
Thasks
|
|
|
|
|
I would expect undefined behaviour if you have a Unicode build.
The lfFaceName member is of type TCHAR[LF_FACESIZE] (see LOGFONT structure (Windows)[^]). So it must be
_tcscpy(lf.lfFaceName, _T("Arial"));
|
|
|
|
|
I have for "Character set" a value of "NOT SET" in that case I don't think I need the _T macro
I have re-built a test application just display this dialog box as every test took me a long time
to set up each test
I going to try lf.Height either 0 or neg and see if it formats it better
thanks for all your help
|
|
|
|
|
There is another error in your code. You have to initialise all members of your LOGFONT structure; usually by clearing them all before setting specific members:
memset(&lf, 0, sizeof(lf));
|
|
|
|
|
thanks
lfHeight
Value
Meaning
> 0 The font mapper transforms this value into device units and matches it against the cell height of the available fonts.
0 The font mapper uses a default height value when it searches for a match.
< 0 The font mapper transforms this value into device units and matches its absolute value against the character height of the available fonts.
Not quite sure what the above means but my question is the units sepcfied on the Crect parm of CStatic:Create the same as the units for lfHeight and lfWidth so if the width of my static control
is 20 and I specify 3 for lfWidth and I have 5 characters the would = 15 units
Thanks
|
|
|
|
|
I'm writing a quick options dialog app, but am a little rusty with my MFC. In short, I have a list box to the left and a property sheet containing pages corresponding to the items in the list box. However, I want to hide the tab control of the property sheet and move the pages up to match the top of the list box.
Hiding the tab control is easy: CPropertySheet::GetTabControl()->ShowWindow(FALSE)
I then went down the path of grabbing the rects of things and subtracting, but I can't help but think I'm making this more complicated than it needs to be. (I did this once back in 2005, but don't have that code and can't remember what I did.)
|
|
|
|
|
The MSDN article has apparently been removed, but someone here has posted most of the code from it.
"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
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
|
Ah, that's what I needed. Thank you very much.
|
|
|
|
|
You are welcome!
|
|
|
|