Custom CRect Question

I have a custom rectangle class that inherits from CRect:

class CCustomRect : public CRect
{
private:
  CPoint m_maxPt;
  COLORREF m_color;
  TCHAR text[50];
public:
  CCustomRect(RECT* source, CPoint pt, COLORREF rgb);
  RECT* RectBase();
  void Update(RECT* r);
}

Inheritance has worked well until I found myself needing to create the 
RectBase function (above) to return the rectangle dimensions.

CRect does not seem to have any methods that can be called to return the 
base class's RECT value.

I could take CRect::Size and construct a rectangle to return, but this seems 
a bit much.

My other alternative seems to be to not inherit from CRect, but rather 
include it as a member variable. I don't really like this idea, though.

Is there a simple way to write the code for RectBase? CRect has several 
operators, including the "operator =" that copies the dimensions of a 
rectangle to CRect. Could my custom class use this operator in some way, or 
did I negate that ability whenever I inherited the CRect class?

Any thoughts? Suggestions? 


0
jp2code
7/20/2007 3:55:27 PM
vc.mfc 33608 articles. 0 followers. Follow

17 Replies
1071 Views

Similar Articles

[PageSpeed] 57

You shouldn't even need RectBase function.
CRect has an operator that converts a CRect class into a LPRECT or LPCRECT.

in other words
CCustomRect Rect;
GetWindowRect(&Rect);

should compile without a single message from the compiler.

Anyway, as far as inherting from a CRect or containing a CRect object goes, 
it all depends on what you are doing, and what is CCustomRect used for. 
What is CCustomRect used for?

If you are enhacing CRect then inherit from it.  If you need an object that 
happens to have a Rectangle as an attribute then contain is the way to go.


 class CCustomRect
 {
 private:
  CPoint m_maxPt;
  COLORREF m_color;
  TCHAR text[50];
  CRect Rect;
 public:
  CCustomRect(const RECT *source, CPoint pt, COLORREF rgb);
  CCustomRect(const RECT &source, CPoint pt, COLORREF rgb);
  const RECT& RectBase() { return Rect; }
  void Update(const RECT &r);
  void Update(const RECT *r);
 }

AliR.


"jp2code" <poojo.com/mail> wrote in message 
news:OEaelZuyHHA.3564@TK2MSFTNGP04.phx.gbl...
>I have a custom rectangle class that inherits from CRect:
>
> class CCustomRect : public CRect
> {
> private:
>  CPoint m_maxPt;
>  COLORREF m_color;
>  TCHAR text[50];
> public:
>  CCustomRect(RECT* source, CPoint pt, COLORREF rgb);
>  RECT* RectBase();
>  void Update(RECT* r);
> }
>
> Inheritance has worked well until I found myself needing to create the 
> RectBase function (above) to return the rectangle dimensions.
>
> CRect does not seem to have any methods that can be called to return the 
> base class's RECT value.
>
> I could take CRect::Size and construct a rectangle to return, but this 
> seems a bit much.
>
> My other alternative seems to be to not inherit from CRect, but rather 
> include it as a member variable. I don't really like this idea, though.
>
> Is there a simple way to write the code for RectBase? CRect has several 
> operators, including the "operator =" that copies the dimensions of a 
> rectangle to CRect. Could my custom class use this operator in some way, 
> or did I negate that ability whenever I inherited the CRect class?
>
> Any thoughts? Suggestions?
> 


0
AliR3470 (3236)
7/20/2007 4:29:08 PM
"jp2code" <poojo.com/mail> wrote in message 
news:OEaelZuyHHA.3564@TK2MSFTNGP04.phx.gbl...

>I have a custom rectangle class that inherits from CRect:
>
> CRect does not seem to have any methods that can be called to return the 
> base class's RECT value.

CRect is effectively derived from RECT (actually from tagRECT but I guess 
this is because RECT has to work in both C and C++ - don't quote me)  so you 
can have

RECT & CMyRect::rect()
{
    return *(RECT *)(CRect *)this;
}

const RECT & CMyRect::rect() const
{
    return *(const RECT *)(const CRect *)this;
}

if you really want to be pedantic :-)

[ I am always wary of using RECT at all, and prefer CRect,  because its copy 
constructor and assignment operator is implicit, and it offends my sense of 
Cplusplusiness, though perhaps it shouldn't.    I have also never liked the 
RECT * conversion of CRect - it just feels horrible converting an object to 
a pointer.]

Dave
-- 
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mzusers/mailinglist.htm


0
dave9996 (486)
7/20/2007 4:37:36 PM
Thanks Mr. Webber.

That's what I was needing. I had done something similar, but I was returning 
a pointer (RECT*) instead of the address (RECT&).

Would this have caused different results? The whole topic of pointers verses 
addresses has always been a little muddled in my brain.

> CRect is effectively derived from RECT (actually from tagRECT but I guess 
> this is because RECT has to work in both C and C++ - don't quote me)  so 
> you can have
>
> RECT & CMyRect::rect()
> {
>    return *(RECT *)(CRect *)this;
> }
>
> const RECT & CMyRect::rect() const
> {
>    return *(const RECT *)(const CRect *)this;
> }
>
> if you really want to be pedantic :-)
>
> [ I am always wary of using RECT at all, and prefer CRect,  because its 
> copy constructor and assignment operator is implicit, and it offends my 
> sense of Cplusplusiness, though perhaps it shouldn't.    I have also never 
> liked the RECT * conversion of CRect - it just feels horrible converting 
> an object to a pointer.]
>
> Dave
> -- 
> David Webber
> Author of 'Mozart the Music Processor'
> http://www.mozart.co.uk
> For discussion/support see
> http://www.mozart.co.uk/mzusers/mailinglist.htm
>
> 


0
jp2code
7/20/2007 6:38:50 PM
"jp2code" <poojo.com/mail> wrote in message 
news:uQrL50vyHHA.4476@TK2MSFTNGP06.phx.gbl...

> That's what I was needing. I had done something similar, but I was 
> returning a pointer (RECT*) instead of the address (RECT&).
>
> Would this have caused different results? The whole topic of pointers 
> verses addresses has always been a little muddled in my brain.

Pointers *are* addresses.

If you have

int n=3;

and

int *pn = &i;

Then the pointer pn is the address where the number 3 (in this case) resides 
in memory.   pn and n are not interchangeable!   n is the number; pn is its 
address.  You can get the number from the address (it's *pn) and the address 
from the number (it's &n) but they are different things.

References are more subtle.  They're like pointers which can be used for 
many syntax purposes interchangeably with the the object itself.  So if you 
have

int &r = n;

r is another way of referring to n.   It's a pseudo-pointer, if you like, to 
n, (in that the information it indirectly encapsulates is actually the 
address of n)  but now you can use it for many purposes as if it were n.

Coming back to RECT abd CRect:

The CRect class is essentially a wrapper around RECT.   Because of the 
inheritance, its data elements  (left, top, right, bottom) are exactly those 
of RECT, and so CRect *is* a RECT with methods added, trnasforming it from C 
to C++.

Now for some reason, which I think is a BIG mistake, when they designed 
CRect they gave it two members of the form

 CRect::operator LPRECT();
 CRect::operator LPCRECT() const;

which cast a CRect to a pointer to a RECT.  It just muddies the waters: 
objects do *not* need to be cast to pointers to themselves.

Consider Windows API functions which take a pointer to a RECT.  For example:

BOOL GetClientRect( HWND hWnd, RECT *prect );

In the old days of C one called it with

RECT R;
GetClientRect( hWnd, &R );        // &R is apointer to R

and one can call it with

CRect r;
GetClientRect( hWnd, &r );        // &r is apointer to r

But the existence of the cast operator means you can also write

CRect r;
GetClientRect( hWnd, r );

r is a CRect, but in fact it is cast to a pointer to itself when 
GetClientRect is called.

Why on earth would anyone want to do that just to avoid typing the & - it 
just looks totally confusing!!!????   Someone tell me I'm not alone here!

Dave
---- 
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mzusers/mailinglist.htm


















>> CRect is effectively derived from RECT (actually from tagRECT but I guess 
>> this is because RECT has to work in both C and C++ - don't quote me)  so 
>> you can have
>>
>> RECT & CMyRect::rect()
>> {
>>    return *(RECT *)(CRect *)this;
>> }
>>
>> const RECT & CMyRect::rect() const
>> {
>>    return *(const RECT *)(const CRect *)this;
>> }
>>
>> if you really want to be pedantic :-)
>>
>> [ I am always wary of using RECT at all, and prefer CRect,  because its 
>> copy constructor and assignment operator is implicit, and it offends my 
>> sense of Cplusplusiness, though perhaps it shouldn't.    I have also 
>> never liked the RECT * conversion of CRect - it just feels horrible 
>> converting an object to a pointer.]
>>
>> Dave
>> -- 
>> David Webber
>> Author of 'Mozart the Music Processor'
>> http://www.mozart.co.uk
>> For discussion/support see
>> http://www.mozart.co.uk/mzusers/mailinglist.htm
>>
>>
>
> 

0
dave9996 (486)
7/20/2007 10:21:12 PM
On Fri, 20 Jul 2007 10:55:27 -0500, "jp2code" <poojo.com/mail> wrote:

>I have a custom rectangle class that inherits from CRect:
>
>class CCustomRect : public CRect
>{
>private:
>  CPoint m_maxPt;
>  COLORREF m_color;
>  TCHAR text[50];
*****
Is there some odd reason you enjoy creating code that can have buffer overflow errors?  Is
there any reason not to use a CString here, which would make a LOT more sense!

Also, if you adopt the m_ naming convention, use it consistently (m_text), or don't use it
at all, but a mixed representation like this leads only to confusion!
*****
>public:
>  CCustomRect(RECT* source, CPoint pt, COLORREF rgb);
****
Is it ever valid to have a NULL source rectangle?  If not, make it RECT &.  Then the
compiler will tend to catch errors.  Presumably, the body looks like

CCustomRect::CCustomRect(RECT * source, CPoint pt, COLORREF rgb) : CRect(source) { m_color
= rgb; m_maxPt = pt; text[0] = _T('\0'); }

but it might have been nice to show that.  But I would *strongly* advise against using
something as quaint as a TCHAR[50] for a string!
*****
>  RECT* RectBase();
*****
Get rid of the above line, it serves no useful purpose.
*****
>  void Update(RECT* r);
>}
>
>Inheritance has worked well until I found myself needing to create the 
>RectBase function (above) to return the rectangle dimensions.
*****
Why?  You can simply use your class in any context in which a RECT would be valid!
*****
>
>CRect does not seem to have any methods that can be called to return the 
>base class's RECT value.
*****
Not clear why you need this at all; in any case, the CRect class has operator LPRECT()
which will give you an address of the object.  Since, for some reason, you chose to return
a RECT *, the operator is already defined.  
*****						
>
>I could take CRect::Size and construct a rectangle to return, but this seems 
>a bit much.
>
>My other alternative seems to be to not inherit from CRect, but rather 
>include it as a member variable. I don't really like this idea, though.
*****
Since you have inherited from CRect, you have inherited operator LPRECT() and operator
LPCRECT().  And note that a CRect is interchangeable with a RECT in arguments.
******
>
>Is there a simple way to write the code for RectBase? CRect has several 
>operators, including the "operator =" that copies the dimensions of a 
>rectangle to CRect. Could my custom class use this operator in some way, or 
>did I negate that ability whenever I inherited the CRect class?
*****
It seems that you are trying to do something the hard way.  You don't need an operator for
this purpose!   Have you actually tried to simply use your class in a place a CRect is
required?  It compiles and works perfectly without any effort!  I just tried it and it
works just fine.
					joe

*****
>
>Any thoughts? Suggestions? 
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15974)
7/22/2007 6:24:10 AM
You mean "pointers vs. REFERENCES", because both pointers and references are addresses.

Largely, it appears to be a fine point of syntax, rather than anything really deep.
However, a reference variable must always be assigned a value, e.g.,

Thing * x;
is a valid declaration, but
Thing & x;
is not.  You can write
Thing & x = x_reference_returning_expression_here;
but you cannot write
Thing & x = NULL;

Once a reference is assigned, it cannot be changed, e.g.,

Thing * x;
....
x = x_pointer_returning_expression_here;
....
x = different_x_pointer_returning_exprfession_here;

but that would not be legal for Thing & x; it must be initialized and cannot thereafter be
changed.   The most common form of this is as parameters.  It means you don't need to
specify the & operator at the call site.

Thing x;
SomeFunction(x);

void SomeFunction(Thing & x)
   {
    if(x.value == 3)
      ... do something
   }

Thing x;
SomeOtherFunction(&x);
void SomeOtherFunction(Thing * x)
    {
     if(x->value == 3)
       ... do something else
    }

For example,the most efficient way to pass a CString to a function is to use const CString
&, e.g.,

CString s;
SomeFuntion(s);

void SomeFunction(const CString & s) ....

It is also convenient that you can eliminate the & at the call site

CString s;
SomeDifferentFunction(s);

void SomeDifferentFunction(CString & s)
   {
    s += _T("Test");
   }

allows the modification of s.  One side effect is that with references, it is much harder
to pass a NULL argument inadvertently.
					joe

On Fri, 20 Jul 2007 13:38:50 -0500, "jp2code" <poojo.com/mail> wrote:

>Thanks Mr. Webber.
>
>That's what I was needing. I had done something similar, but I was returning 
>a pointer (RECT*) instead of the address (RECT&).
>
>Would this have caused different results? The whole topic of pointers verses 
>addresses has always been a little muddled in my brain.
>
>> CRect is effectively derived from RECT (actually from tagRECT but I guess 
>> this is because RECT has to work in both C and C++ - don't quote me)  so 
>> you can have
>>
>> RECT & CMyRect::rect()
>> {
>>    return *(RECT *)(CRect *)this;
>> }
>>
>> const RECT & CMyRect::rect() const
>> {
>>    return *(const RECT *)(const CRect *)this;
>> }
>>
>> if you really want to be pedantic :-)
>>
>> [ I am always wary of using RECT at all, and prefer CRect,  because its 
>> copy constructor and assignment operator is implicit, and it offends my 
>> sense of Cplusplusiness, though perhaps it shouldn't.    I have also never 
>> liked the RECT * conversion of CRect - it just feels horrible converting 
>> an object to a pointer.]
>>
>> Dave
>> -- 
>> David Webber
>> Author of 'Mozart the Music Processor'
>> http://www.mozart.co.uk
>> For discussion/support see
>> http://www.mozart.co.uk/mzusers/mailinglist.htm
>>
>> 
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15974)
7/23/2007 6:37:15 AM
But on the whole, did you really need such a function?  For example, you don't need it to
do an assignment, e.g.,

	CMyRect mr;
	...set values
	CRect r = mr;

works perfectly and does not require a special operator to get the CRect!  Show why you
think you need this function!
				joe

On Fri, 20 Jul 2007 13:38:50 -0500, "jp2code" <poojo.com/mail> wrote:

>Thanks Mr. Webber.
>
>That's what I was needing. I had done something similar, but I was returning 
>a pointer (RECT*) instead of the address (RECT&).
>
>Would this have caused different results? The whole topic of pointers verses 
>addresses has always been a little muddled in my brain.
>
>> CRect is effectively derived from RECT (actually from tagRECT but I guess 
>> this is because RECT has to work in both C and C++ - don't quote me)  so 
>> you can have
>>
>> RECT & CMyRect::rect()
>> {
>>    return *(RECT *)(CRect *)this;
>> }
>>
>> const RECT & CMyRect::rect() const
>> {
>>    return *(const RECT *)(const CRect *)this;
>> }
>>
>> if you really want to be pedantic :-)
>>
>> [ I am always wary of using RECT at all, and prefer CRect,  because its 
>> copy constructor and assignment operator is implicit, and it offends my 
>> sense of Cplusplusiness, though perhaps it shouldn't.    I have also never 
>> liked the RECT * conversion of CRect - it just feels horrible converting 
>> an object to a pointer.]
>>
>> Dave
>> -- 
>> David Webber
>> Author of 'Mozart the Music Processor'
>> http://www.mozart.co.uk
>> For discussion/support see
>> http://www.mozart.co.uk/mzusers/mailinglist.htm
>>
>> 
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15974)
7/23/2007 6:39:23 AM
> Is there some odd reason you enjoy creating code that can have buffer 
> overflow errors?  Is
> there any reason not to use a CString here, which would make a LOT more 
> sense!

I used to write code that relied a little too heavily on CString and CString 
functions, and it got to where I was not using some well known, reliable, 
and fast C/C++ tools for doing the same things. So, my manager told me to 
stop using CString for a while.

> Also, if you adopt the m_ naming convention, use it consistently (m_text), 
> or don't use it
> at all, but a mixed representation like this leads only to confusion!

Understood. Thanks for the reprimand. My manager does not require this, and 
it is just something I have started doing on my own to match the coding 
conventions from some of these MVPs. Often, I adopt code that is 20 years 
old that does not have a "pre m_". To change those variables would mean 
making lots of changes, but I try to make sure that any variables I add 
follow this technique so that I have better programming techniques.

> ...make it RECT &.  Then the compiler will tend to catch errors.

Done. Thanks for the tip!

Your suggestions have been greatly appreciated!

Thank you. 


0
jp2code
7/23/2007 1:40:01 PM
I must admit: I have found old code that I wrote that neglected to send the 
address of the CRect. Since the compiler did not catch it, I never knew I 
did anything wrong.

Later, I would see how the code was written, and wonder how it ever 
compiled.

Now I know!

I did fix the botched up code, though.

"David Webber" wrote:
> In the old days of C one called it with
>
> RECT R;
> GetClientRect( hWnd, &R );        // &R is apointer to R
>
> and one can call it with
>
> CRect r;
> GetClientRect( hWnd, &r );        // &r is apointer to r
>
> But the existence of the cast operator means you can also write
>
> CRect r;
> GetClientRect( hWnd, r );
>
> r is a CRect, but in fact it is cast to a pointer to itself when 
> GetClientRect is called.


0
jp2code
7/23/2007 1:45:17 PM
I'm designing my own progress bar, which will contain rectangles of 
sub-progress bar information.

When I initialize the custom progress bar, I will pass it the "rectangled" 
dimensions of the desktop window. The custom class will size itself (and its 
sub-progress bars) at a percentage of the viewable region of a small 
device's screen, and return the overall dimensions of the outer, enclosing 
progress bar.

If I get it to work, it will look very nice! (Key here is IF)

> But on the whole, did you really need such a function?  For example, you 
> don't need it to
> do an assignment, e.g.,
>
> CMyRect mr;
> ...set values
> CRect r = mr;
>
> works perfectly and does not require a special operator to get the CRect! 
> Show why you
> think you need this function!
> joe
>


0
jp2code
7/23/2007 1:51:54 PM
See below...
On Mon, 23 Jul 2007 08:40:01 -0500, "jp2code" <poojo.com/mail> wrote:

>> Is there some odd reason you enjoy creating code that can have buffer 
>> overflow errors?  Is
>> there any reason not to use a CString here, which would make a LOT more 
>> sense!
>
>I used to write code that relied a little too heavily on CString and CString 
>functions, and it got to where I was not using some well known, reliable, 
>and fast C/C++ tools for doing the same things. So, my manager told me to 
>stop using CString for a while.
****
Silly reason.  I have stopped using any of the primitive and outdated C string library,
and use CString entirely.  Why do you think these are "reliable", or for that matter, that
they are "fast"?  

Avoiding CString is saying "I like to write unreliable code that allows my program to be
attacked by buffer overflow exploits, fail because I miscalculated some fixed length, and
then failed to check buffer limits".  So you have a manager that wants to see the
reliability of products decrease?  Does your manager have the foggiest clue what
abandoning CString *really* means?  
*****
>
>> Also, if you adopt the m_ naming convention, use it consistently (m_text), 
>> or don't use it
>> at all, but a mixed representation like this leads only to confusion!
>
>Understood. Thanks for the reprimand. My manager does not require this, and 
>it is just something I have started doing on my own to match the coding 
>conventions from some of these MVPs. Often, I adopt code that is 20 years 
>old that does not have a "pre m_". To change those variables would mean 
>making lots of changes, but I try to make sure that any variables I add 
>follow this technique so that I have better programming techniques.
****
I consider most of these naming conventions to have negative value.  I tend to REMOVE the
m_ and HN prefixes from code that passes over my desk, because it increases the
readability.

Adding variables that use a different convention is far, far, far worse a practice.  Use
one convention or the other, but never mix them.  This is a catastrophe, because the
reader never knows what to expect!
				joe

*****
>
>> ...make it RECT &.  Then the compiler will tend to catch errors.
>
>Done. Thanks for the tip!
>
>Your suggestions have been greatly appreciated!
>
>Thank you. 
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15974)
7/23/2007 4:42:29 PM
It isn't very hard to do this.  But it still doesn't explain why you need some special
operator to extract the rectangle part of the subclass.
					joe

On Mon, 23 Jul 2007 08:51:54 -0500, "jp2code" <poojo.com/mail> wrote:

>I'm designing my own progress bar, which will contain rectangles of 
>sub-progress bar information.
>
>When I initialize the custom progress bar, I will pass it the "rectangled" 
>dimensions of the desktop window. The custom class will size itself (and its 
>sub-progress bars) at a percentage of the viewable region of a small 
>device's screen, and return the overall dimensions of the outer, enclosing 
>progress bar.
>
>If I get it to work, it will look very nice! (Key here is IF)
>
>> But on the whole, did you really need such a function?  For example, you 
>> don't need it to
>> do an assignment, e.g.,
>>
>> CMyRect mr;
>> ...set values
>> CRect r = mr;
>>
>> works perfectly and does not require a special operator to get the CRect! 
>> Show why you
>> think you need this function!
>> joe
>>
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15974)
7/24/2007 4:56:20 AM
"Joseph M. Newcomer" wrote:
> It isn't very hard to do this.

For a seasoned pro like you, I'm sure it is easy. But I don't have many 
years of development under my belt, and I hardly ever have to draw anything 
to the screen. It has taken me too long to find examples that can be molded 
to what I want to do. I am also the only VC developer, and (by default) the 
only MFC developer here. The other two developers here are Linux, Borland, 
and Assembly developers. When I went to school, I learned on Visual Studio. 
Now I'm using eMbedded VC.

> ...it still doesn't explain why you need some special
> operator to extract the rectangle part of the subclass.

Originally, I wanted the rectangle dimensions so I would know what size 
object to paint on the screen. Since reading responses to this thread and 
the "Drawing Layers" thread, my approach has changed - hopefully for the 
better!

I've read more than one request for my code, so here it is (without the 
headers). The object "m_img" in CMainDlg::DisplayImage (called from 
CMainDlg::OnPaint) is not defined below, because it works. I'm sure my 
coding style will disturb some (white space disturbs me), but everyone is 
different.

My hope is that someone like Mr. joe Flounder can see what I'm trying to do 
and point out any wrong practices.


//---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// ZRectBar class
ZRectBar::ZRectBar(RECT &r, COLORREF rgb) {
  m_cr = rgb;
  m_pt[eBL] = CPoint(r.bottom, r.left);
  m_pt[eBR] = CPoint(r.bottom, r.left); // innitialize to left size
  m_pt[eBM] = CPoint(r.bottom, r.right);
  m_pt[eTL] = CPoint(r.top, r.left);
  m_pt[eTR] = CPoint(r.top, r.left);    // innitialize to left size
  m_pt[eTM] = CPoint(r.top, r.right);
}
//---------------------------------------------------------------------------
ZRectBar::~ZRectBar() {
}
//---------------------------------------------------------------------------
void ZRectBar::Update(double ratio) { // only updates right side
  m_pt[eTR].x = int(m_pt[eTM].x * ratio + 0.5);
  m_pt[eTR].y = int(m_pt[eTM].y * ratio + 0.5);
  m_pt[eBR].x = int(m_pt[eBM].x * ratio + 0.5);
  m_pt[eBR].y = int(m_pt[eBM].y * ratio + 0.5);
}
//---------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// ZProgressBar class
ZProgressBar::ZProgressBar(RECT &r) : m_active(FALSE) {
  if (m_rb[eBASE] != NULL) delete m_rb[eBASE];
  if (m_rb[eSESS] != NULL) delete m_rb[eSESS];
  if (m_rb[eFRAM] != NULL) delete m_rb[eFRAM];
  SetPosition(r);
}
//---------------------------------------------------------------------------
ZProgressBar::~ZProgressBar() {
  delete[] &m_rb;
}
//---------------------------------------------------------------------------
DWORD ZProgressBar::PaintDC(CDC* dc) {
  CPen penBase(PS_SOLID, 1, m_rb[eBASE]->m_cr);
  CPen* oldpen = dc->SelectObject(&penBase);
  CBrush brushBase(m_rb[eBASE]->m_cr);
  CBrush* oldbrush = dc->SelectObject(&brushBase);
  dc->Polygon(m_rb[eBASE]->m_pt, 4);
  // Frame
  CPen penFram(PS_SOLID, 1, m_rb[eFRAM]->m_cr);
  dc->SelectObject(&penFram);
  CBrush brushFram(m_rb[eFRAM]->m_cr);
  dc->SelectObject(&brushFram);
  dc->Polygon(m_rb[eFRAM]->m_pt, 4);
  // Session
  CPen penSess(PS_SOLID, 1, m_rb[eSESS]->m_cr);
  dc->SelectObject(&penSess);
  CBrush brushSess(m_rb[eSESS]->m_cr);
  dc->SelectObject(&brushSess);
  dc->Polygon(m_rb[eSESS]->m_pt, 4);

  dc->SelectObject(oldpen);
  dc->SelectObject(oldbrush);
  return 0;
}
//---------------------------------------------------------------------------
void ZProgressBar::SetPosition(RECT& r) {
  CPoint center(CRect(r).CenterPoint());
  CRect rect;
  COLORREF cr;
  int x(3 * center.x / 4);   // =  3/4 * center.x
  int y(1 * center.y / 10);  // = 1/10 * center.y
  int top1(center.y - y),    top2(center.y - (y - 5));
  int left(center.x - x),    right(center.x + x);
  int bottom1(center.y + y), bottom2(center.y + (y - 5));
  if (m_rb[eBASE] == NULL) {
    rect = CRect(CPoint(top1, left), CPoint(bottom1, right));
    cr = RGB(0xC0, 0xC0, 0xC0); // silver
    m_rb[eBASE] = new ZRectBar(rect, cr);
  }
  if (m_rb[eFRAM] == NULL) {
    rect = CRect(CPoint(top1, left), CPoint(bottom1, left));
    cr = RGB(0xFF, 0x00, 0x00); // red
    m_rb[eFRAM] = new ZRectBar(rect, cr);
  }
  if (m_rb[eSESS] == NULL) {
    rect = CRect(CPoint(top2, left), CPoint(bottom2, left));
    cr = RGB(0x00, 0x80, 0xFF); // blue-ish
    m_rb[eSESS] = new ZRectBar(rect, cr);
  }
}
//---------------------------------------------------------------------------
void ZProgressBar::Update(ZInfoPacket *pkt) {
  m_active = TRUE;
  if ((pkt->sessions != 0) && (pkt->frames != 0)) { // prevent division by 
zero
    m_rb[eSESS]->Update(double(pkt->session / pkt->sessions));
    m_rb[eFRAM]->Update(double(pkt->frame   / pkt->frames));
  }
}
//---------------------------------------------------------------------------
void CMainDlg::DisplayImage(CPaintDC *dc) {
  BOOL ok(m_bitmap.GetBitmap(&m_img.Bmp));
  CBitmap *poldbmp;
  if (ok) {
    CDC mDC;
    mDC.CreateCompatibleDC(dc);
    poldbmp = mDC.SelectObject(&m_bitmap);
    if (poldbmp != NULL) {
      m_pic = m_img.SetBounds(&m_rect);
      if (m_progressBar->Active() == TRUE) {
        m_progressBar->PaintDC(&mDC); // paint the progress bar to memDC 
before copying it
      }
      ok = dc->StretchBlt(m_pic.left, m_pic.top, m_pic.Width(), 
m_pic.Height(), &mDC,
                  m_img.BmpR.left, m_img.BmpR.top, m_img.BmpR.Width(), 
m_img.BmpR.Height(), SRCCOPY);
      if (!ok) {
        outList.ConcatTail(CString(TEXT("\n")) + 
CString(SysErrorMessage(GetLastError())));
      }
      mDC.SelectObject(poldbmp); // restore the DC to original state
      //mDC.DeleteDC();
      m_bitmap.DeleteObject();
    }
    mDC.ReleaseAttribDC();
  } else {
    ShowLastError(TEXT("GetBitmap Failed"));
    m_img.SetKind(kNONE); // prevents an err loop
    Invalidate(); // messes up the background
  }
}
//---------------------------------------------------------------------------


0
jp2code
7/24/2007 1:51:51 PM
But it really isn't very hard.  I teach this on the first day of MFC programming, where we
draw some text inside a rectangle on the screen.  Two hours later, the students are
dragging the text and rectangle around.  It well and truly isn't very hard.

You need one good book on Windows programming that has a chapter on graphics in it.  Note
that the Linux, Borland, and Assembly programmers will not find anything about how to draw
rectangles in their C/C++ books either.  But a single book on X-windows programming will
tell you about creating a GC (Graphics Context) and drawing to it.  Borland is a company
that produces all kinds of things, so I don't know what they're using, but if it is
Delphi, then the Delphi language was designed to support WIndows graphics, and it WILL
have a chapter on drawing rectangles, because it is just like having a Windows book.  No
assembly programmer has a clue as to how to draw a rectangle, and they certainly won't
find it in the Intel assembly code manuals or the Microsoft Assembler manual.  So the art
is looking in the right place.  But that doesn't make it hard.  Really.  

Key is to understand that x increases to the right and y increases downward.  After you've
mastered that, the rest is pretty easy.  Rectangle draws 4-sided vertical/horizontal
aligned things, MoveTo/LineTo draw lines, Ellipse draws ellipses and circles.  At this
point, you've mastered 90% of what you ever need to know to do drawing of all non-text
stuff.

The other 10% you pick up as needed.  Bitmaps are messy, no question, but once you have an
example piece of code (from the MSDN)  you now have 90% of what you ever need to know
about bitmaps.  Polygons are a bit harder, pie-chart graphics, curves, and Beziers follow,
but the number of times I've had to use those is very small.  I always have to reread the
manual when I use them.

You will be surprised at how easy it is once you get started.

By the way, text isn't hard either, just tedious.

There are over 30 parameters of the DC you can manipulate, but the key ones are
	dc.SelectObject(&pen);
	dc.SelectObject(&brush);
	dc.SelectObject(&font);
	dc.SetBkMode(...);
	dc.SetTextColor(...);
	dc.SetROP2(...); of which you usually need R2_COPY and one of
		R2_XORPEN, R2_NOTXORPEN, and R2_NOTPEN
	
and after that, the need for other parameters drops off rapidly.

Finally, there are mapping modes.  These are both cool and powerful, and you typically
don't get into these for a while.  The calls are
	dc.SetMapMode(...)
	dc.SetWindowOrg(...)
	dc.SetViewportOrg(...)
	dc.SetWindowExt(...)
	dc.SetViewportExt(...)
and for these you can download my Viewport Explorer (I got tired of having to read the
manual each time I used these, which was about twice a year).

There are esoteric things like paths, transform matrices, and clipping regions, and you
can deal with them as you need to, but I don't use them too often.  

So there's your study outline for graphics.  There are a huge number of DC calls for
drawing and manipulation of DC state, but I've given you the study guide for 99% of what
you need to know in the explicit list of calls above.

You can also download the programs for the Win32 book from my MVP Tips site and explore
the more esoteric aspects of pens, brushes, DCs, bitmap calls, etc.
					joe
*****



On Tue, 24 Jul 2007 08:51:51 -0500, "jp2code" <poojo.com/mail> wrote:

>"Joseph M. Newcomer" wrote:
>> It isn't very hard to do this.
>
>For a seasoned pro like you, I'm sure it is easy. But I don't have many 
>years of development under my belt, and I hardly ever have to draw anything 
>to the screen. It has taken me too long to find examples that can be molded 
>to what I want to do. I am also the only VC developer, and (by default) the 
>only MFC developer here. The other two developers here are Linux, Borland, 
>and Assembly developers. When I went to school, I learned on Visual Studio. 
>Now I'm using eMbedded VC.
>
>> ...it still doesn't explain why you need some special
>> operator to extract the rectangle part of the subclass.
>
>Originally, I wanted the rectangle dimensions so I would know what size 
>object to paint on the screen. Since reading responses to this thread and 
>the "Drawing Layers" thread, my approach has changed - hopefully for the 
>better!
>
>I've read more than one request for my code, so here it is (without the 
>headers). The object "m_img" in CMainDlg::DisplayImage (called from 
>CMainDlg::OnPaint) is not defined below, because it works. I'm sure my 
>coding style will disturb some (white space disturbs me), but everyone is 
>different.
>
>My hope is that someone like Mr. joe Flounder can see what I'm trying to do 
>and point out any wrong practices.
>
>
>//---------------------------------------------------------------------------
>/////////////////////////////////////////////////////////////////////////////
>// ZRectBar class
>ZRectBar::ZRectBar(RECT &r, COLORREF rgb) {
>  m_cr = rgb;
>  m_pt[eBL] = CPoint(r.bottom, r.left);
>  m_pt[eBR] = CPoint(r.bottom, r.left); // innitialize to left size
>  m_pt[eBM] = CPoint(r.bottom, r.right);
>  m_pt[eTL] = CPoint(r.top, r.left);
>  m_pt[eTR] = CPoint(r.top, r.left);    // innitialize to left size
>  m_pt[eTM] = CPoint(r.top, r.right);
>}
****
You can probably compute these on the fly rather than one at a time.  Just store the CRect
and the color.
****
>//---------------------------------------------------------------------------
>ZRectBar::~ZRectBar() {
>}
>//---------------------------------------------------------------------------
>void ZRectBar::Update(double ratio) { // only updates right side
>  m_pt[eTR].x = int(m_pt[eTM].x * ratio + 0.5);
>  m_pt[eTR].y = int(m_pt[eTM].y * ratio + 0.5);
>  m_pt[eBR].x = int(m_pt[eBM].x * ratio + 0.5);
>  m_pt[eBR].y = int(m_pt[eBM].y * ratio + 0.5);
>}
>//---------------------------------------------------------------------------
>/////////////////////////////////////////////////////////////////////////////
>// ZProgressBar class
>ZProgressBar::ZProgressBar(RECT &r) : m_active(FALSE) {
>  if (m_rb[eBASE] != NULL) delete m_rb[eBASE];
>  if (m_rb[eSESS] != NULL) delete m_rb[eSESS];
>  if (m_rb[eFRAM] != NULL) delete m_rb[eFRAM];
>  SetPosition(r);
>}
>//---------------------------------------------------------------------------
>ZProgressBar::~ZProgressBar() {
>  delete[] &m_rb;
>}
>//---------------------------------------------------------------------------
>DWORD ZProgressBar::PaintDC(CDC* dc) {
>  CPen penBase(PS_SOLID, 1, m_rb[eBASE]->m_cr);
****
Given you apparently want a solid rectangle, you can simply select the HOLLOW_PEN and you
don't need to create a pen of the same color as the brush
*****
>  CPen* oldpen = dc->SelectObject(&penBase);
>  CBrush brushBase(m_rb[eBASE]->m_cr);
>  CBrush* oldbrush = dc->SelectObject(&brushBase);
>  dc->Polygon(m_rb[eBASE]->m_pt, 4);
*****
But Rectangle would be simpler....
****
>  // Frame
>  CPen penFram(PS_SOLID, 1, m_rb[eFRAM]->m_cr);
>  dc->SelectObject(&penFram);
>  CBrush brushFram(m_rb[eFRAM]->m_cr);
>  dc->SelectObject(&brushFram);
>  dc->Polygon(m_rb[eFRAM]->m_pt, 4);
>  // Session
>  CPen penSess(PS_SOLID, 1, m_rb[eSESS]->m_cr);
>  dc->SelectObject(&penSess);
>  CBrush brushSess(m_rb[eSESS]->m_cr);
>  dc->SelectObject(&brushSess);
>  dc->Polygon(m_rb[eSESS]->m_pt, 4);
*****
You are probably making this whole problem more complex than it needs to be.  You dissect
the rectangle parameters, then reassemble them in a complex fashion, when just keeping a
small number of values should suffice.  Don't think of the problem in terms of rectangles;
those are a tiny implementation detail.  Think instead of percentages of the total and
percentages of the values you are trying to display, and the problem becomes MUCH simpler!
*****
>
>  dc->SelectObject(oldpen);
>  dc->SelectObject(oldbrush);
>  return 0;
>}
>//---------------------------------------------------------------------------
>void ZProgressBar::SetPosition(RECT& r) {
>  CPoint center(CRect(r).CenterPoint());
>  CRect rect;
>  COLORREF cr;
>  int x(3 * center.x / 4);   // =  3/4 * center.x
>  int y(1 * center.y / 10);  // = 1/10 * center.y
>  int top1(center.y - y),    top2(center.y - (y - 5));
>  int left(center.x - x),    right(center.x + x);
>  int bottom1(center.y + y), bottom2(center.y + (y - 5));
>  if (m_rb[eBASE] == NULL) {
>    rect = CRect(CPoint(top1, left), CPoint(bottom1, right));
>    cr = RGB(0xC0, 0xC0, 0xC0); // silver
*****
If this is supposed to be the background, it should be
	cr = ::GetSysColor(COLOR_3DFACE);
so it follows the user's color scheme
*****
>    m_rb[eBASE] = new ZRectBar(rect, cr);
****
You don't need a 'new' here, and it probably isn't a good idea.  I think this code is
needlessly complex...you are having problems because you are trying to create difficult
solutions for simple problems
****
>  }
>  if (m_rb[eFRAM] == NULL) {
>    rect = CRect(CPoint(top1, left), CPoint(bottom1, left));
>    cr = RGB(0xFF, 0x00, 0x00); // red
>    m_rb[eFRAM] = new ZRectBar(rect, cr);
>  }
>  if (m_rb[eSESS] == NULL) {
>    rect = CRect(CPoint(top2, left), CPoint(bottom2, left));
>    cr = RGB(0x00, 0x80, 0xFF); // blue-ish
>    m_rb[eSESS] = new ZRectBar(rect, cr);
>  }
>}
>//---------------------------------------------------------------------------
>void ZProgressBar::Update(ZInfoPacket *pkt) {
>  m_active = TRUE;
>  if ((pkt->sessions != 0) && (pkt->frames != 0)) { // prevent division by 
>zero
*****
This appears to be the important part of the work.  But I need to understand what all
these parameters are really doing in terms of the display
*****
>    m_rb[eSESS]->Update(double(pkt->session / pkt->sessions));
>    m_rb[eFRAM]->Update(double(pkt->frame   / pkt->frames));
>  }
>}
>//---------------------------------------------------------------------------
*****
WHat is confusing here is trying to figure out exactly what you are doing.

I think what I heard is that you need a progress bar with three components in it, for
example'

##########***************$$$$$$$$$$$$$$$$$

where each of those represents a color.  Is this essentially correct?

Trying to figure out if this is what intended from the code is a bit difficult.

Rather than showing me the code, give a precise definition of what you are trying to
accomplish, not in terms of rectangles, but in terms of the logical goal.  What are the
actual parameters of what you are trying to display?  

I can't quite figure out what you mean by 

*****When I initialize the custom progress bar, I will pass it the "rectangled" 
*****dimensions of the desktop window. The custom class will size itself (and its 
*****sub-progress bars) at a percentage of the viewable region of a small 
*****device's screen, and return the overall dimensions of the outer, enclosing 
*****progress bar.

First, I think this is the wrong approach.  The owner of the progress bar will size the
progress bar to some size.  So everything else is in terms of some other set of
parameters, such as total progress percentage, and sub-percentages.  (Note that I had a
14-year-old doing a "gas gauge" of two colors in less than an hour of total investment of
learning, for the remaining fuel and weapons of a "tank" in a video game we were writing,
but that was because we started with a specification instead of the code.  I don't have a
clear specification of what you are trying to do, and I think the code is vastly more
complicated than it needs to be as a consequence of having a complex specification).

So tell me not about "rectangled" values but tell me about what values are being displayed
in terms of the abstract values, and the code will probably be very simple to write.  I
can tell you right now it will not involve Polygon calls, or 'new' calls, or worrying
about sending rectangles in.  Tell me what those numbers mean without showing a single
line of code.  Tell me what the user is going to see.  Without a clear explanation of the
goals of the code, I can't figure out what the code is trying to accomplish, but I have a
real suspicion that the code here is vastly more complex than it needs to be.
*****
               
>void CMainDlg::DisplayImage(CPaintDC *dc) {
****
CDC & dc 
would be a better choice of parameter here
****
>  BOOL ok(m_bitmap.GetBitmap(&m_img.Bmp));
>  CBitmap *poldbmp;
>  if (ok) {
>    CDC mDC;
>    mDC.CreateCompatibleDC(dc);
>    poldbmp = mDC.SelectObject(&m_bitmap);
>    if (poldbmp != NULL) {
>      m_pic = m_img.SetBounds(&m_rect);
>      if (m_progressBar->Active() == TRUE) {
>        m_progressBar->PaintDC(&mDC); // paint the progress bar to memDC 
>before copying it
****
m_progessBar->PaintDC(mDC); // use CDC & dc for the parameter

Before you start worrying about flicker, it is more important to have a clear piece of
code.  You can optimize for flicker later.
****
>      }
>      ok = dc->StretchBlt(m_pic.left, m_pic.top, m_pic.Width(), 
>m_pic.Height(), &mDC,
>                  m_img.BmpR.left, m_img.BmpR.top, m_img.BmpR.Width(), 
>m_img.BmpR.Height(), SRCCOPY);
*****
The StretchBlt is very suspicious.  I'm concerned about this level of complexity.  You are
trying to draw, if I understand what I think, three "stacked" bars.  StretchBlt doesn't
fit this model at all.
*****
>      if (!ok) {
>        outList.ConcatTail(CString(TEXT("\n")) + 
>CString(SysErrorMessage(GetLastError())));
>      }
>      mDC.SelectObject(poldbmp); // restore the DC to original state
****
No, this is just restoring the old bitmap.  And RestoreDC would be a bette choice.
****
>      //mDC.DeleteDC();
>      m_bitmap.DeleteObject();
>    }
>    mDC.ReleaseAttribDC();
****
Why?
****
>  } else {
>    ShowLastError(TEXT("GetBitmap Failed"));
>    m_img.SetKind(kNONE); // prevents an err loop
>    Invalidate(); // messes up the background
>  }
>}
>//---------------------------------------------------------------------------
>
*****
Overall, your problems are coming not from a failure to understand Windows graphics, but
from failing to have a simple, clean specification of what you are trying to display.  All
you need to do is compute three, or four, rectangles, and draw them.  It is vastly simpler
than what I see here.    The result of a complex specification is a complex
implementation.  Just state a very simple specification of what these mean, and the code
is going to be really easy.
				joe
*****
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15974)
7/24/2007 7:08:33 PM
The application is a small dialog based form.

As the User makes selections from a drop down menu, the "wallpaper" is 
updated to reflect a relevant subject for the topic and to visually cue the 
User in to the section he is working in.

One of the sections include the option to download a log file from the 
machine or upload a configuration file to the machine. The number of bytes 
in the files are larger than the machine's OS can handle (similar to the 
65,535 limit), so the machine breaks the file size down into sessions and 
frames.

Our progress bar needs to keep track of the current frame, total frames in 
the session, the session number, and total number of sessions.

I already have a "wallpaper" for the main window. If the progress bar is 
active, I need to add the progress bar data to the "wallpaper" image before 
it is displayed.

I hope that helps shed some light on what my code is trying to do.

So, would your "Win32 Programming" be a good book for this?

"Joseph M. Newcomer" wrote:
> Overall, your problems are coming not from a failure to understand Windows 
> graphics, but
> from failing to have a simple, clean specification of what you are trying 
> to display.  All
> you need to do is compute three, or four, rectangles, and draw them.  It 
> is vastly simpler
> than what I see here.    The result of a complex specification is a 
> complex
> implementation.  Just state a very simple specification of what these 
> mean, and the code
> is going to be really easy.
> joe
> *****
> Joseph M. Newcomer [MVP]
> email: newcomer@flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm 


0
jp2code
7/24/2007 7:52:44 PM
See below...
On Tue, 24 Jul 2007 14:52:44 -0500, "jp2code" <poojo.com/mail> wrote:

>The application is a small dialog based form.
>
>As the User makes selections from a drop down menu, the "wallpaper" is 
>updated to reflect a relevant subject for the topic and to visually cue the 
>User in to the section he is working in.
>
>One of the sections include the option to download a log file from the 
>machine or upload a configuration file to the machine. The number of bytes 
>in the files are larger than the machine's OS can handle (similar to the 
>65,535 limit), so the machine breaks the file size down into sessions and 
>frames.
>
>Our progress bar needs to keep track of the current frame, total frames in 
>the session, the session number, and total number of sessions.
****
So what this sounds like is you have several "bars", one of which is a progress along the
dimension of sessions completed, one of which is completion of the current session, and
one which is the progress in the current frame.  So this isn't a stacked progress bar, it
sounds like three bars
#############################
$$$$$$$$$$$$$$$$$
**************

so that the top is the total session transmission; when it hits 100%, everything is
transferred.
The second one is the progress along the current session.  When it hits 100%, the top bar
increments by one position, and the second one resets to 0 to indicate the start of the
nex session.
A session consists of a number of frames, and consequently the bottom bar indicates the
percentage of frames in the current session.  When it hits 100%, the second bar increments
by one unit.

Now the real issue is that you have made this REALLY complicated when it doesn';t need to
be.  For example, I would handle this by creating a modeless dialog box which contains
three progress controls.  If I wanted to make it really compact, I'd create a modeless
dialog with no border.  I would then size it to the width of the window.  Then I would
send it messages to set the range and position of each of the bars.  If I wanted
everything really compact, I'd create  progress controls without borders (which is not an
international humanitarian progress control organization).

Now, in the dialog, in its OnSize handler, I'd respond by computing 1/3 the height, and
the full width, and adjust the progress bars so they filled the entire dialog.   

Note that there is virtually no graphical programming required to accomplish this.

Compute the number of sessions.  Send a message
	dlg->SendMessage(UWM_SET_RANGE, (WPARAM)bartype, (LPARAM)value);
	dlg->SendMessage(UWM_SET_POS, (WPARAM)bartype, (LPARAM)value);

where you have something like typedef enum {Sessions, Session, Frame} BARTYPE;

When the transfer completed, I'd hide or destroy the modeless dialog. 

Because this is a modeless dialog, there will be no flicker in doing the update.  

You have taken a REALLY simple problem and made it REALLY complex.

Note that if you WERE to draw these directly on the surface of your bitmap, you would
invalidate ONLY the tiny region you required to have redrawn, say, from the rightmost end
of the old progress position to the rightmost end of the new progress position.  No
flicker.  No need for a memory DC at all!  But why go through so much effort to solve such
a simple problem?  You want three progress bars, use the existing progress bars!  You can
use PBM_SETBARCOLOR to change the colors of the bars so they look different from each
other.
				joe
*****
>
>I already have a "wallpaper" for the main window. If the progress bar is 
>active, I need to add the progress bar data to the "wallpaper" image before 
>it is displayed.
>
>I hope that helps shed some light on what my code is trying to do.
>
>So, would your "Win32 Programming" be a good book for this?
*****
If you were doing graphics, I might recommend it (but recall that I'm very biased about
the book).  But the problem is so much simpler that I wouldn't see spending all that money
to solve it.
				joe
*****
>
>"Joseph M. Newcomer" wrote:
>> Overall, your problems are coming not from a failure to understand Windows 
>> graphics, but
>> from failing to have a simple, clean specification of what you are trying 
>> to display.  All
>> you need to do is compute three, or four, rectangles, and draw them.  It 
>> is vastly simpler
>> than what I see here.    The result of a complex specification is a 
>> complex
>> implementation.  Just state a very simple specification of what these 
>> mean, and the code
>> is going to be really easy.
>> joe
>> *****
>> Joseph M. Newcomer [MVP]
>> email: newcomer@flounder.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm 
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15974)
7/24/2007 8:56:01 PM
Send me private email and I'll send you a fully-worked-out example of a 3-progress-bar
modeless dialog that sits at the bottom of the window.  Note the dialog is resizable and
watch what it does when you resize it.
					joe

On Tue, 24 Jul 2007 14:52:44 -0500, "jp2code" <poojo.com/mail> wrote:

>The application is a small dialog based form.
>
>As the User makes selections from a drop down menu, the "wallpaper" is 
>updated to reflect a relevant subject for the topic and to visually cue the 
>User in to the section he is working in.
>
>One of the sections include the option to download a log file from the 
>machine or upload a configuration file to the machine. The number of bytes 
>in the files are larger than the machine's OS can handle (similar to the 
>65,535 limit), so the machine breaks the file size down into sessions and 
>frames.
>
>Our progress bar needs to keep track of the current frame, total frames in 
>the session, the session number, and total number of sessions.
>
>I already have a "wallpaper" for the main window. If the progress bar is 
>active, I need to add the progress bar data to the "wallpaper" image before 
>it is displayed.
>
>I hope that helps shed some light on what my code is trying to do.
>
>So, would your "Win32 Programming" be a good book for this?
>
>"Joseph M. Newcomer" wrote:
>> Overall, your problems are coming not from a failure to understand Windows 
>> graphics, but
>> from failing to have a simple, clean specification of what you are trying 
>> to display.  All
>> you need to do is compute three, or four, rectangles, and draw them.  It 
>> is vastly simpler
>> than what I see here.    The result of a complex specification is a 
>> complex
>> implementation.  Just state a very simple specification of what these 
>> mean, and the code
>> is going to be really easy.
>> joe
>> *****
>> Joseph M. Newcomer [MVP]
>> email: newcomer@flounder.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm 
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15974)
7/24/2007 11:48:47 PM
Reply:

Similar Artilces:

Publisher Question #7
How do I overlap stacked objects so that the top object appears to be tucked INTO the object behind it? Arrange menu, Order... or alt+F6, bring to the front alt+Shift+F6, send to the back. There is also bring forward or send backward with no keyboard equivalent in the Arrange menu, Order. -- Mary Sauer MSFT MVP http://office.microsoft.com/ http://msauer.mvps.org/ news://msnews.microsoft.com "elenaperez" <elenaperez@discussions.microsoft.com> wrote in message news:27A8A0DB-B944-4CFE-B406-C12379F04522@microsoft.com... > How do I overlap stacked objects so that the top ...

Custom form for specified Document Properties
Under Word 2007, by default, there's a huge number of keystrokes required to get to Custom Document Properties. I'd like to make this simple. Two ways forward have thwarted me, esp. since Word Help is no longer working properly for me (I'm getting empty Office 2010 stuff - subject of a separate post.) i) build a form (I've forgotten how to do this.) ii) explore the opportunities suggested by the ribbon under Developer|Templates|Document Panel. The dialog box that opens looks like it might supply what I want. Normally, the Help system would send me where I wa...

A question in an interview
I was asked to write a function described below with C/C++ in 20 minutes. Implement a function that prints all posible combinations of the characters in a string. These combinations range in length from one to the length of the string. Two combinations that differ only in ordering of their characters are the same combination. In other words,"12" and "31" are different combinations from the input string"123",but 21 is the same as "12". Any good suggestion? I'd start by asking for a better definition of the problem. What if the input string is &qu...

Beginner question
I am creating a query that counts how many times each classification is being used in our organization. But, I need it to pull up only the classifications that have a person in them. Here's how it looks now: Column 1: Field = Classification; Table = pos info; Total = Group By Column 2: Field = Class Code; Talbe = pos info; Total = Group By Column 3: Field = Count Of Classification: Count(*); Total = Expression I need it to pull up the Classifications that, within each same record, the field "IncumbentLast" Is Not Null. Thanks for your help. Hi - Add the field "Incum...

DPM 2010 question
Hello, I have some questions about Data Protection Manager 2010: 1. How to configure a Protection Group, when this Protection Group makes the backup, to overwrite a tape that is already linked to a Protection Group? 2. How to configure a Protection Group to perform the backup of folders that are already configured on another Protection Group? 3. How to catalog a tape manually (changing the catalog name)? 4, How to link two or more Protection Groups to one tape? 5. How to erase a tape that is linked to a Protection Group? 6. How to mark the tape that is linked t...

VBA question: Sheets() vs. Worksheets()?
Are these the same functions? Sheets can include chart sheets. Worksheets no -- Don Guillett SalesAid Software dguillett1@austin.rr.com "Mondrogan" <mondrogan@comcast.net> wrote in message news:FoudnVzS_MQXq2nYnZ2dnUVZ_qCmnZ2d@comcast.com... > Are these the same functions? > So I should always use Sheets() rather than Worksheets()? Sounds like Worksheets() functionality is a subset of Sheets(). "Don Guillett" <dguillett1@austin.rr.com> wrote in message news:%23gVmVAAZHHA.1400@TK2MSFTNGP06.phx.gbl... > Sheets can include chart sheets. Works...

get report to display custom label rather than numeric data in tex
i've searched for ages trying to find a similar query already answered but have had no luck - apologies if i'm using poor terminology, i'm not that good on access in a report, one of the the text box fields records 'site' which is coded as a number 1-8. is it possible to use some sort of code (i'm thinking perhaps some kind of IIf statement from the looks of other replies) to get the report to display "Bolton" instead of 1, Burnley instead of 2 and so on? thanks in advance for help. "Emelina Bumsquash" <EmelinaBumsquash@discussions.microso...

Customizing a CDateTimeCtrl to show other calendars than Gregorian's
I'm experiencing a really hard time while looking for some info about how to change programmatically the gregorian calendar in an MFC VC++6 app using a DateTimePicker control. Actually, I'm trying to show programmatically a Hijri Calendar and it's not working at all even if I changed my local (regional) settings to: Arabic(Morocco)... And getting some info from the Web didn't end with something... Can someone send a hint? Best Regards, Abu Abdillah ...

Does anyone process large numbers of customer returns?
Our VAR just confirmed that the Returns Management module doesn't have the capability to electronically (rather than manually) input the receiving transactions. This is a deal-breaker for us, since we process large numbers of returns on a regular basis and it would be prohibitive for us to have an army of clerks entering the data. Do any of you currently process (or know of anyone that does) significant returns through GP? If so, how are they handled - manually, or do you have a third party solution to do so? Any info would be appreciated! -- Bud Cool, Accounting System Manager H...

Deactivated Custom entity records in CRM 4.0
1- How can I see all records that were deactivated are displayed when I use the Quick Find view to show customized entities in Microsoft Dynamics CRM 4.0. By default Deactivated records was not displayed in Quick Find. 2- Also I want Deactivated custom entity records be visible in the associated view in Microsoft Dynamics CRM 4.0. -- Mohsen Ahmadi, msnahm@hotmail.com IR-0912 *** **** You can change this behaviour in the customizations.xml. To do this do the following: - Export the customizations for the custom entity - Unzip and open the customizations.xml file in a text editor (notepad...

Custom PO Export
I am trying to customize a PO in Store Operations Manager. I can Customize the XML file used to print the PO and get the fields I need. My problem is with the XSL file used to export a PO. If I customize this for the same information the fields are empty. Is it possible to customize the data in the export? And are there any resources on how to accomplish this? Thank you for your Assistance in advance Richard ...

Can't load custom dictionary
Running Publisher98. Suddenly after a reload it tells me it can't load the custom dictionary and will use the default dictionary. Can I fix this? Where do I find the dictionaries? What is their extension? Doesn't seem to be DIC. Do you have Office 97? OFF97: Error Message When You Try to Check Spelling, or Misspellings Are Not Corrected http://support.microsoft.com/kb/185906/en-us What version Windows? What version Office? -- Mary Sauer MSFT MVP http://office.microsoft.com/ http://msauer.mvps.org/ news://msnews.microsoft.com http://officebeta.iponet.net/en-us/publisher/FX10064...

Customize Outlook Today 2000
Having installed outlook 2000 on a pc with xp home addition, i can't customize the toady screen. I click on the menu but nothing happens. Cheers Corrie The following MSKB article provides the fix for this issue. OL2000: You Cannot Customize Outlook Today After You Install Critical Update 813489 for Internet Explorer: http://support.microsoft.com/default.aspx?scid=kb;EN-US;820575 -- Jocelyn Fiorello MVP - Outlook *** Replies sent to my e-mail address will probably not be answered -- please reply only to the newsgroup to preserve the message thread. *** "Corrie" <co...

Custom Project Workspace Not in Dropdown
I created a new Workspace Template for PS 2007 according to the instructions posted on the Project Experts site: http://www.projectserverhelp.com/Lists/Posts/Post.aspx?ID=21 However, after everything proceeding as described and the template showing up in the available templates for creating new general sites, the template still does not show as an option for default site provisioning. I'm an admin on the server and for PWA and I didn't receive any error messages. Any ideas what the problem could be? Thanks in advance. Hello PublicMike, Have you restated the...

Custom Form Question #2
I have created two almost identical custom forms for Outlook 2007 in an exchange environment. The forms are based on the task form, and simply have a second tab that we each sign off on the steps of our projects as they go. We create those forms by going to action|new "custom" form. However, one of the forms appears as a task with a task icon in the task folder when I create it. But, the other shows up in the task folder, but with a post item icon, that is the little yellow sticky note with the blue push pin in it. I can't find where you set this attribute and why one form i...

Linking Case to Custom Entity
I want to create a link similar to the link that allows me to look at CONTACTS and view CASES associated with that CONTACT except: I have added a new ENTITY called SOFTWARE VERSION and a relationship to the existing CASE Entity (and added to the main form). I want to be able to go to my SOFTWARE VERSION entity and view all CASES associated with that SOFTWARE VERSION. How can I do this? Anyone? Creating a many-to-one relationship on your new entity with the Case entity will do the trick. Use the incidentid field to link Case with your SoftwareVersion entity. This relationship will pl...

SBS 2003 to 2008 Migration, and other Server migration questions
Hi, I'm in the midst of planing a migration from SBS 2003 to SBS 2008. I did a swing migration 3 or so years ago when I switched out HW for SBS 2003, and it worked well, only a couple of minor problems I had to deal with. I"m not opposed to purchasing the rights again, but do see that MS has documention for the same purpose, so I was wondering from those who have done migrations, which did you use, and why? Also, I have a 2nd domain controller, and a couple of other member servers (all 2003 Server), and I would like to figure out if I could do some kind of migration ...

How to populate State and Country values for custom picklist fields programmatically?
I added custom picklist fields in for STATE and COUNTRY in leads, contacts, and accounts entities. How do I populate the values in those fields without having to add the possible values manually? I'm told that the STRINGMAP table in MSCRM database contains the picklist values, but I'm not familiar with how it interacts with the application. I also know that Microsoft does not support manipulating this table directly. Has anyone overcome this problem? Thanks! Phillip Hi Phillip, don't use the stringmap table. All your values will be lost the second you publish any schema o...

LDB question
A while ago we had a discussion about persistent connection (which I tried once and never since). I plan to check "BE-MDB-open-status" on it's LDB, ie. LDB exists = MDB is open LDB doesn't exists = MDB is closed (I suppose that in such case persistent connection cannot be used.) But after an accident it may result incorrect MDB status since LDB may not be deleted. Is there a safer way to check if MDB is open? TIA Vlado How about OpenDatabase with the Exclusive option. If the file is already in use, that should fail. Testing the LDB is not ideal: it applies only when t...

Excel question #22
I was wondering how to make something happen. I would like to take a formula in excel and assign it to a cell. When the user enters a number it takes that number and applies it to the formula and returns the number. Here is an example. (x / 60)=y if user enter 10 then the formula should return .166~ where x is the users input and y is the returned answer. If you could help me I would appreciate it. Have user input into cell A1. In cell B1, enter the formula: =A1/60 HTH, Elkar "shaver21560@hotmail.com" wrote: > I was wondering how to make something happen. I wo...

SBS 2000 Exchange Question
Has anyone seen the following before? "Microsoft Exchange Server reported error 0x80040600: Unknown error 0x80040600" This is effecting only one of 20 clients on XP Pro using Outlook XP. KB didn't have a reference to it. Thanks -- KnetWerks http://support.microsoft.com/?kbid=814441 -- John Oliver, Jr. MCSE, MCT, CCNA, Exchange MVP Microsoft Certified Partner "KnetWerks" <KnetWerks@discussions.microsoft.com> wrote in message news:7E9C06AF-EEBC-4DE3-B978-C48C713DA7E2@microsoft.com... > Has anyone seen the following before? > > "Microsoft Exc...

Custom Listbox (again)
Ok, I finally got the custom listbox to work by using a modeless dialog and the got the timer to work by creating message pump when the left button is down (similar to CTracker) and now I can scroll. Now I'm trying to get rid of the flicker when it scrolls. I'm using a memory dc but it doesn't help. There is no erase background message for a dialog. The WM_CTLCOLOR message just allows for setting the brush. Can someone help with this one? Thanks "Michael" <NOSPAMmao@vnet.net> wrote in message news:e$RJhNgTDHA.2148@TK2MSFTNGP11.phx.gbl... > ...There is no erase...

Custom Doc Sizes
Can I create a custom paper size in the paper size option drop menu under the "printer and paper" tab in page setup (Pub2003)? I am unable to print custom size posters. To print them at 23" by 35" for example, I have to size them to the existing size 28"X40", and this is a great waste of materials. Thank you, all. This article addresses Publisher 2002, I assume it is the same for 2003 PUB2002: Large Banners and Posters Printed in Separate Sections http://support.microsoft.com/default.aspx?scid=kb;en-us;288201 PUB2000: Large Banners and Posters Are Printed...

RBS and other custom fields are not in olap cubes
HI all I added RBS and other custom fields to olap cube configuration, rebuilted a cube, but those fields do not appear in any of olap cubes. Please help!!!!!!!!!!! They should, make sure they are added into the Project, Task and Assignment cubes to be sure... -- Regards, Ben. "Rimcha" wrote: > HI all > I added RBS and other custom fields to olap cube configuration, > rebuilted a cube, but those fields do not appear in any of olap cubes. > Please help!!!!!!!!!!! > . > ...

"Save changes" question.
Why do I get a message asking me if I want to save the changes made to the spreadsheet when I didn't do a thing to it? I merely opened it up, looked at data in a cell, and closed it. Nothing was changed, added, deleted, or even highlighted. Thanks, Hi Paul Maybe you have Volatile function See the following webpage http://www.decisionmodels.com/calcsecretsi.htm -- Regards Ron de Bruin http://www.rondebruin.nl "Paul" <anonymous@discussions.microsoft.com> wrote in message news:2218b01c45d53$921b06d0$a601280a@phx.gbl... > Why do I get a message asking me if I ...