-
GetClientRect and DrawEdge not working on a UserControl?
Please tell me why the following code does nothing.. Place a picture box on
a usercontrol and name it picBackground. Paste this code into the
usercontrol, then drop the control onto a form...
Const BDR_RAISEDINNER = &H4
Const BDR_RAISEDOUTER = &H1
Const BF_BOTTOM = &H8
Const BF_LEFT = &H1
Const BF_RIGHT = &H4
Const BF_TOP = &H2
Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
Private Sub UserControl_Resize()
Dim di As Long
Dim rc As RECT
di = GetClientRect(picBackground.hwnd, rc)
di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER, BF_BOTTOMRIGHT)
End Sub
I am expecting the picture box to have a thin raise border around it. It
ends up not having anything...
Hmmm.. can anyone clue me in?
-
Re: GetClientRect and DrawEdge not working on a UserControl?
I answered the question myself...
If you want this to happen on an action like a Form_Load or a
UserControl_Resize, you MUST have the AutoRedraw proporty of the control you
are getting the hdc of set to TRUE!
"Raymond R Cassick" <raycass@adelphia.net> wrote in message
news:39122d38@news.devx.com...
> Please tell me why the following code does nothing.. Place a picture box
on
> a usercontrol and name it picBackground. Paste this code into the
> usercontrol, then drop the control onto a form...
>
> Const BDR_RAISEDINNER = &H4
> Const BDR_RAISEDOUTER = &H1
>
> Const BF_BOTTOM = &H8
> Const BF_LEFT = &H1
> Const BF_RIGHT = &H4
> Const BF_TOP = &H2
> Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
> Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
>
>
> Private Sub UserControl_Resize()
>
> Dim di As Long
> Dim rc As RECT
>
> di = GetClientRect(picBackground.hwnd, rc)
> di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
> di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER, BF_BOTTOMRIGHT)
>
> End Sub
>
> I am expecting the picture box to have a thin raise border around it. It
> ends up not having anything...
>
> Hmmm.. can anyone clue me in?
>
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
I answered the question myself...
If you want this to happen on an action like a Form_Load or a
UserControl_Resize, you MUST have the AutoRedraw proporty of the control you
are getting the hdc of set to TRUE!
"Raymond R Cassick" <raycass@adelphia.net> wrote in message
news:39122d38@news.devx.com...
> Please tell me why the following code does nothing.. Place a picture box
on
> a usercontrol and name it picBackground. Paste this code into the
> usercontrol, then drop the control onto a form...
>
> Const BDR_RAISEDINNER = &H4
> Const BDR_RAISEDOUTER = &H1
>
> Const BF_BOTTOM = &H8
> Const BF_LEFT = &H1
> Const BF_RIGHT = &H4
> Const BF_TOP = &H2
> Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
> Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
>
>
> Private Sub UserControl_Resize()
>
> Dim di As Long
> Dim rc As RECT
>
> di = GetClientRect(picBackground.hwnd, rc)
> di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
> di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER, BF_BOTTOMRIGHT)
>
> End Sub
>
> I am expecting the picture box to have a thin raise border around it. It
> ends up not having anything...
>
> Hmmm.. can anyone clue me in?
>
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
Raymond,
True, but there's a more efficient way to do it, which is placing your
drawing code in the Paint event of the control or form. Setting the
AutoRedraw property to True will consume far more resources, since VB has to
maintain an internal bitmap image of the object.
BTW, in your Resize event, you'll need to add a call to InvalidateRect()
passing a Null (zero) as the RECT and set the bErase argument to TRUE (1) in
order for things to work, especially seeing that you're painting borders on
the DC:
Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long,
lpRect As Any, ByVal bErase As Long) As Long
Call InvalidateRect(UserControl.hWnd, ByVal 0&, 1)
.. . . . . . . . . . . . . . . . . . . . . .
Klaus H. Probst, MVP
http://www.vbbox.com/
http://www.mvps.org/ccrp/
Please post/reply to the newsgroup(s)
"Raymond R Cassick" <raycass@adelphia.net> wrote in message
news:39122fd3$1@news.devx.com...
> I answered the question myself...
>
> If you want this to happen on an action like a Form_Load or a
> UserControl_Resize, you MUST have the AutoRedraw proporty of the control
you
> are getting the hdc of set to TRUE!
>
> "Raymond R Cassick" <raycass@adelphia.net> wrote in message
> news:39122d38@news.devx.com...
> > Please tell me why the following code does nothing.. Place a picture box
> on
> > a usercontrol and name it picBackground. Paste this code into the
> > usercontrol, then drop the control onto a form...
> >
> > Const BDR_RAISEDINNER = &H4
> > Const BDR_RAISEDOUTER = &H1
> >
> > Const BF_BOTTOM = &H8
> > Const BF_LEFT = &H1
> > Const BF_RIGHT = &H4
> > Const BF_TOP = &H2
> > Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
> > Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
> >
> >
> > Private Sub UserControl_Resize()
> >
> > Dim di As Long
> > Dim rc As RECT
> >
> > di = GetClientRect(picBackground.hwnd, rc)
> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER,
BF_BOTTOMRIGHT)
> >
> > End Sub
> >
> > I am expecting the picture box to have a thin raise border around it. It
> > ends up not having anything...
> >
> > Hmmm.. can anyone clue me in?
> >
> >
> >
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
Raymond,
True, but there's a more efficient way to do it, which is placing your
drawing code in the Paint event of the control or form. Setting the
AutoRedraw property to True will consume far more resources, since VB has to
maintain an internal bitmap image of the object.
BTW, in your Resize event, you'll need to add a call to InvalidateRect()
passing a Null (zero) as the RECT and set the bErase argument to TRUE (1) in
order for things to work, especially seeing that you're painting borders on
the DC:
Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long,
lpRect As Any, ByVal bErase As Long) As Long
Call InvalidateRect(UserControl.hWnd, ByVal 0&, 1)
.. . . . . . . . . . . . . . . . . . . . . .
Klaus H. Probst, MVP
http://www.vbbox.com/
http://www.mvps.org/ccrp/
Please post/reply to the newsgroup(s)
"Raymond R Cassick" <raycass@adelphia.net> wrote in message
news:39122fd3$1@news.devx.com...
> I answered the question myself...
>
> If you want this to happen on an action like a Form_Load or a
> UserControl_Resize, you MUST have the AutoRedraw proporty of the control
you
> are getting the hdc of set to TRUE!
>
> "Raymond R Cassick" <raycass@adelphia.net> wrote in message
> news:39122d38@news.devx.com...
> > Please tell me why the following code does nothing.. Place a picture box
> on
> > a usercontrol and name it picBackground. Paste this code into the
> > usercontrol, then drop the control onto a form...
> >
> > Const BDR_RAISEDINNER = &H4
> > Const BDR_RAISEDOUTER = &H1
> >
> > Const BF_BOTTOM = &H8
> > Const BF_LEFT = &H1
> > Const BF_RIGHT = &H4
> > Const BF_TOP = &H2
> > Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
> > Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
> >
> >
> > Private Sub UserControl_Resize()
> >
> > Dim di As Long
> > Dim rc As RECT
> >
> > di = GetClientRect(picBackground.hwnd, rc)
> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER,
BF_BOTTOMRIGHT)
> >
> > End Sub
> >
> > I am expecting the picture box to have a thin raise border around it. It
> > ends up not having anything...
> >
> > Hmmm.. can anyone clue me in?
> >
> >
> >
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
why is that? Does this do cleanup for the GetClientRect function?
"Klaus H. Probst" <kprobst@vbbox.com> wrote in message
news:39125cb0@news.devx.com...
> Raymond,
>
> True, but there's a more efficient way to do it, which is placing your
> drawing code in the Paint event of the control or form. Setting the
> AutoRedraw property to True will consume far more resources, since VB has
to
> maintain an internal bitmap image of the object.
>
> BTW, in your Resize event, you'll need to add a call to InvalidateRect()
> passing a Null (zero) as the RECT and set the bErase argument to TRUE (1)
in
> order for things to work, especially seeing that you're painting borders
on
> the DC:
>
> Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long,
> lpRect As Any, ByVal bErase As Long) As Long
>
> Call InvalidateRect(UserControl.hWnd, ByVal 0&, 1)
>
>
> . . . . . . . . . . . . . . . . . . . . . .
> Klaus H. Probst, MVP
> http://www.vbbox.com/
> http://www.mvps.org/ccrp/
>
> Please post/reply to the newsgroup(s)
>
>
> "Raymond R Cassick" <raycass@adelphia.net> wrote in message
> news:39122fd3$1@news.devx.com...
> > I answered the question myself...
> >
> > If you want this to happen on an action like a Form_Load or a
> > UserControl_Resize, you MUST have the AutoRedraw proporty of the control
> you
> > are getting the hdc of set to TRUE!
> >
> > "Raymond R Cassick" <raycass@adelphia.net> wrote in message
> > news:39122d38@news.devx.com...
> > > Please tell me why the following code does nothing.. Place a picture
box
> > on
> > > a usercontrol and name it picBackground. Paste this code into the
> > > usercontrol, then drop the control onto a form...
> > >
> > > Const BDR_RAISEDINNER = &H4
> > > Const BDR_RAISEDOUTER = &H1
> > >
> > > Const BF_BOTTOM = &H8
> > > Const BF_LEFT = &H1
> > > Const BF_RIGHT = &H4
> > > Const BF_TOP = &H2
> > > Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
> > > Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
> > >
> > >
> > > Private Sub UserControl_Resize()
> > >
> > > Dim di As Long
> > > Dim rc As RECT
> > >
> > > di = GetClientRect(picBackground.hwnd, rc)
> > > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
> > > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER,
> BF_BOTTOMRIGHT)
> > >
> > > End Sub
> > >
> > > I am expecting the picture box to have a thin raise border around it.
It
> > > ends up not having anything...
> > >
> > > Hmmm.. can anyone clue me in?
> > >
> > >
> > >
> >
> >
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
why is that? Does this do cleanup for the GetClientRect function?
"Klaus H. Probst" <kprobst@vbbox.com> wrote in message
news:39125cb0@news.devx.com...
> Raymond,
>
> True, but there's a more efficient way to do it, which is placing your
> drawing code in the Paint event of the control or form. Setting the
> AutoRedraw property to True will consume far more resources, since VB has
to
> maintain an internal bitmap image of the object.
>
> BTW, in your Resize event, you'll need to add a call to InvalidateRect()
> passing a Null (zero) as the RECT and set the bErase argument to TRUE (1)
in
> order for things to work, especially seeing that you're painting borders
on
> the DC:
>
> Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long,
> lpRect As Any, ByVal bErase As Long) As Long
>
> Call InvalidateRect(UserControl.hWnd, ByVal 0&, 1)
>
>
> . . . . . . . . . . . . . . . . . . . . . .
> Klaus H. Probst, MVP
> http://www.vbbox.com/
> http://www.mvps.org/ccrp/
>
> Please post/reply to the newsgroup(s)
>
>
> "Raymond R Cassick" <raycass@adelphia.net> wrote in message
> news:39122fd3$1@news.devx.com...
> > I answered the question myself...
> >
> > If you want this to happen on an action like a Form_Load or a
> > UserControl_Resize, you MUST have the AutoRedraw proporty of the control
> you
> > are getting the hdc of set to TRUE!
> >
> > "Raymond R Cassick" <raycass@adelphia.net> wrote in message
> > news:39122d38@news.devx.com...
> > > Please tell me why the following code does nothing.. Place a picture
box
> > on
> > > a usercontrol and name it picBackground. Paste this code into the
> > > usercontrol, then drop the control onto a form...
> > >
> > > Const BDR_RAISEDINNER = &H4
> > > Const BDR_RAISEDOUTER = &H1
> > >
> > > Const BF_BOTTOM = &H8
> > > Const BF_LEFT = &H1
> > > Const BF_RIGHT = &H4
> > > Const BF_TOP = &H2
> > > Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
> > > Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
> > >
> > >
> > > Private Sub UserControl_Resize()
> > >
> > > Dim di As Long
> > > Dim rc As RECT
> > >
> > > di = GetClientRect(picBackground.hwnd, rc)
> > > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
> > > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER,
> BF_BOTTOMRIGHT)
> > >
> > > End Sub
> > >
> > > I am expecting the picture box to have a thin raise border around it.
It
> > > ends up not having anything...
> > >
> > > Hmmm.. can anyone clue me in?
> > >
> > >
> > >
> >
> >
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
> why is that? Does this do cleanup for the GetClientRect function?
No. It forces the DC ro redraw itself. Try it -- omit the InvalidateRect
call and resize your control. You'll get "ghosted" edges and incorrect
drawing. This is by design, BTW. Windows are not supposed to do a full
redraw on a simple WM_SIZE message.
--
.. . . . . . . . . . . . . . . . . . . . . .
Klaus H. Probst, MVP
http://www.vbbox.com/
http://www.mvps.org/ccrp/
Please post/reply to the newsgroup(s)
-
Re: GetClientRect and DrawEdge not working on a UserControl?
> why is that? Does this do cleanup for the GetClientRect function?
No. It forces the DC ro redraw itself. Try it -- omit the InvalidateRect
call and resize your control. You'll get "ghosted" edges and incorrect
drawing. This is by design, BTW. Windows are not supposed to do a full
redraw on a simple WM_SIZE message.
--
.. . . . . . . . . . . . . . . . . . . . . .
Klaus H. Probst, MVP
http://www.vbbox.com/
http://www.mvps.org/ccrp/
Please post/reply to the newsgroup(s)
-
Re: GetClientRect and DrawEdge not working on a UserControl?
Klaus,
The paint event is unusable as it stops firing when a message box appears.
You have to subclass.
Michael Culley
"Klaus H. Probst" <kprobst@vbbox.com> wrote:
>Raymond,
>
>True, but there's a more efficient way to do it, which is placing your
>drawing code in the Paint event of the control or form. Setting the
>AutoRedraw property to True will consume far more resources, since VB has
to
>maintain an internal bitmap image of the object.
>
>BTW, in your Resize event, you'll need to add a call to InvalidateRect()
>passing a Null (zero) as the RECT and set the bErase argument to TRUE (1)
in
>order for things to work, especially seeing that you're painting borders
on
>the DC:
>
>Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long,
>lpRect As Any, ByVal bErase As Long) As Long
>
>Call InvalidateRect(UserControl.hWnd, ByVal 0&, 1)
>
>
>.. . . . . . . . . . . . . . . . . . . . . .
>Klaus H. Probst, MVP
> http://www.vbbox.com/
> http://www.mvps.org/ccrp/
>
>Please post/reply to the newsgroup(s)
>
>
>"Raymond R Cassick" <raycass@adelphia.net> wrote in message
>news:39122fd3$1@news.devx.com...
>> I answered the question myself...
>>
>> If you want this to happen on an action like a Form_Load or a
>> UserControl_Resize, you MUST have the AutoRedraw proporty of the control
>you
>> are getting the hdc of set to TRUE!
>>
>> "Raymond R Cassick" <raycass@adelphia.net> wrote in message
>> news:39122d38@news.devx.com...
>> > Please tell me why the following code does nothing.. Place a picture
box
>> on
>> > a usercontrol and name it picBackground. Paste this code into the
>> > usercontrol, then drop the control onto a form...
>> >
>> > Const BDR_RAISEDINNER = &H4
>> > Const BDR_RAISEDOUTER = &H1
>> >
>> > Const BF_BOTTOM = &H8
>> > Const BF_LEFT = &H1
>> > Const BF_RIGHT = &H4
>> > Const BF_TOP = &H2
>> > Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
>> > Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
>> >
>> >
>> > Private Sub UserControl_Resize()
>> >
>> > Dim di As Long
>> > Dim rc As RECT
>> >
>> > di = GetClientRect(picBackground.hwnd, rc)
>> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
>> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER,
>BF_BOTTOMRIGHT)
>> >
>> > End Sub
>> >
>> > I am expecting the picture box to have a thin raise border around it.
It
>> > ends up not having anything...
>> >
>> > Hmmm.. can anyone clue me in?
>> >
>> >
>> >
>>
>>
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
Klaus,
The paint event is unusable as it stops firing when a message box appears.
You have to subclass.
Michael Culley
"Klaus H. Probst" <kprobst@vbbox.com> wrote:
>Raymond,
>
>True, but there's a more efficient way to do it, which is placing your
>drawing code in the Paint event of the control or form. Setting the
>AutoRedraw property to True will consume far more resources, since VB has
to
>maintain an internal bitmap image of the object.
>
>BTW, in your Resize event, you'll need to add a call to InvalidateRect()
>passing a Null (zero) as the RECT and set the bErase argument to TRUE (1)
in
>order for things to work, especially seeing that you're painting borders
on
>the DC:
>
>Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long,
>lpRect As Any, ByVal bErase As Long) As Long
>
>Call InvalidateRect(UserControl.hWnd, ByVal 0&, 1)
>
>
>.. . . . . . . . . . . . . . . . . . . . . .
>Klaus H. Probst, MVP
> http://www.vbbox.com/
> http://www.mvps.org/ccrp/
>
>Please post/reply to the newsgroup(s)
>
>
>"Raymond R Cassick" <raycass@adelphia.net> wrote in message
>news:39122fd3$1@news.devx.com...
>> I answered the question myself...
>>
>> If you want this to happen on an action like a Form_Load or a
>> UserControl_Resize, you MUST have the AutoRedraw proporty of the control
>you
>> are getting the hdc of set to TRUE!
>>
>> "Raymond R Cassick" <raycass@adelphia.net> wrote in message
>> news:39122d38@news.devx.com...
>> > Please tell me why the following code does nothing.. Place a picture
box
>> on
>> > a usercontrol and name it picBackground. Paste this code into the
>> > usercontrol, then drop the control onto a form...
>> >
>> > Const BDR_RAISEDINNER = &H4
>> > Const BDR_RAISEDOUTER = &H1
>> >
>> > Const BF_BOTTOM = &H8
>> > Const BF_LEFT = &H1
>> > Const BF_RIGHT = &H4
>> > Const BF_TOP = &H2
>> > Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
>> > Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
>> >
>> >
>> > Private Sub UserControl_Resize()
>> >
>> > Dim di As Long
>> > Dim rc As RECT
>> >
>> > di = GetClientRect(picBackground.hwnd, rc)
>> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
>> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER,
>BF_BOTTOMRIGHT)
>> >
>> > End Sub
>> >
>> > I am expecting the picture box to have a thin raise border around it.
It
>> > ends up not having anything...
>> >
>> > Hmmm.. can anyone clue me in?
>> >
>> >
>> >
>>
>>
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
> The Paint event is unusable as it stops firing when
> a message box appears. You have to subclass.
Michael: ...or don't use message boxes. ;-)
---
Phil Weber
-
Re: GetClientRect and DrawEdge not working on a UserControl?
> The Paint event is unusable as it stops firing when
> a message box appears. You have to subclass.
Michael: ...or don't use message boxes. ;-)
---
Phil Weber
-
Re: GetClientRect and DrawEdge not working on a UserControl?
>> If you want this to happen on an action like a Form_Load or a
>> UserControl_Resize, you MUST have the AutoRedraw proporty
>> of the control you are getting the hdc of set to TRUE!
>
>True, but there's a more efficient way to do it
Okay, this one tickled the fancy. After a prolonged SmartCheck jam
session, here is what I observed VB doing with regard to graphics:
In VB5 SP2/3, for Forms, PictureBoxes, and UserControls (didn't
check PropertyPages, UserDocuments or any other new VB6
graphical control I don't yet know about, but I assume things will
be similar):
- when AutoRedraw is False, the hDC property returns the window's
real DC, and the CLS method is always just an UpdateWindow call.
- anytime the Image property is queried, or when AutoRedraw =
True and any graphics methods are preformed or the hDC property
is queried, VB creates another compatible memory DC and bitmap:
for Forms, the size of the screen; everything else is the size of the
respective window (note on the 1024x768 resolution and 16 bit
color I'm running here, a Form's Image equates to about a 1.5 MB
bitmap, or:
Call GetObject(obj.Image, Len(bm), bm)
With bm
Select Case .bmBitsPixel ' system color depth
Case 2: cb = (.bmWidth * .bmHeight) * (.bmPlanes / 4)
Case 4: cb = (.bmWidth * .bmHeight) * (.bmPlanes / 2)
Case 8: cb = (.bmWidth * .bmHeight) * .bmPlanes
Case 16: cb = (.bmWidth * .bmHeight) * (.bmPlanes * 2)
Case 24: cb = (.bmWidth * .bmHeight) * (.bmPlanes * 3)
Case 32: cb = (.bmWidth * .bmHeight) * (.bmPlanes * 4)
End Select
End With
(I think that's right...)
- the Image property always returns the memory bitmap handle.
- when AutoRedraw = True , hDC always returns the memory DC.
- after the memory bitmap is created, when AutoRedraw is set to
True, VB swaps all GDI objects from the window to the memory DC
and visa versa, when AutoRedraw = False, VB swaps all GDI objects
back to normal and StretchBlt the memory DC onto the form window
DC on each WM_PAINT.
- when AutoRedraw = True, CLS swaps the memory/window GDI
objects back to normal, deletes the memory DC and bitmap, and
we start all over.
- once the memory DC and bitmap are created, they live for the life
of the window, or until CLS is called.
- if the memory DC and bitmap were not created (Image = 0, don't
check it, including IntelliSense, or just watch your favorite memory
monitor), VB then does normal window painting on WM_PAINT.
Addendum: just ran a quick check on VB6/Win2K, and everything
seems about the same, though the memory hits from Image property
creation wasn't as pronounced (might be some kind of caching in
the OS or VB...).
So, with all that, and because we now know that VB suspends a
window's execution when it calls MsgBox, Raymond is either left
with subclassing the PictureBox and calling DrawEdge on each
WM_PAINT, or just setting the PictureBoxes AutoRedraw to true
calling DrawEdge once, and eating a few KBs...
Moral of the story: AutoRedraw isn't such a bad thing, but gets
worse with bigger windows.
--
Brad Martinez, http://www.mvps.org
Please direct questions/replies to the newsgroup
(just goes to show, you put a dangerous tool in the hands of an
insomniac and things get scary... :>)
Klaus H. Probst wrote in message <39125cb0@news.devx.com>...
>Raymond,
>
>True, but there's a more efficient way to do it, which is placing your
>drawing code in the Paint event of the control or form. Setting the
>AutoRedraw property to True will consume far more resources, since VB has to
>maintain an internal bitmap image of the object.
>
>BTW, in your Resize event, you'll need to add a call to InvalidateRect()
>passing a Null (zero) as the RECT and set the bErase argument to TRUE (1) in
>order for things to work, especially seeing that you're painting borders on
>the DC:
>
>Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long,
>lpRect As Any, ByVal bErase As Long) As Long
>
>Call InvalidateRect(UserControl.hWnd, ByVal 0&, 1)
>
>
>. . . . . . . . . . . . . . . . . . . . . .
>Klaus H. Probst, MVP
> http://www.vbbox.com/
> http://www.mvps.org/ccrp/
>
>Please post/reply to the newsgroup(s)
>
>
>"Raymond R Cassick" <raycass@adelphia.net> wrote in message
>news:39122fd3$1@news.devx.com...
>> I answered the question myself...
>>
>> If you want this to happen on an action like a Form_Load or a
>> UserControl_Resize, you MUST have the AutoRedraw proporty of the control
>you
>> are getting the hdc of set to TRUE!
>>
>> "Raymond R Cassick" <raycass@adelphia.net> wrote in message
>> news:39122d38@news.devx.com...
>> > Please tell me why the following code does nothing.. Place a picture box
>> on
>> > a usercontrol and name it picBackground. Paste this code into the
>> > usercontrol, then drop the control onto a form...
>> >
>> > Const BDR_RAISEDINNER = &H4
>> > Const BDR_RAISEDOUTER = &H1
>> >
>> > Const BF_BOTTOM = &H8
>> > Const BF_LEFT = &H1
>> > Const BF_RIGHT = &H4
>> > Const BF_TOP = &H2
>> > Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
>> > Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
>> >
>> >
>> > Private Sub UserControl_Resize()
>> >
>> > Dim di As Long
>> > Dim rc As RECT
>> >
>> > di = GetClientRect(picBackground.hwnd, rc)
>> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
>> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER,
>BF_BOTTOMRIGHT)
>> >
>> > End Sub
>> >
>> > I am expecting the picture box to have a thin raise border around it. It
>> > ends up not having anything...
>> >
>> > Hmmm.. can anyone clue me in?
>> >
>> >
>> >
>>
>>
>
>
-
Re: GetClientRect and DrawEdge not working on a UserControl?
>> If you want this to happen on an action like a Form_Load or a
>> UserControl_Resize, you MUST have the AutoRedraw proporty
>> of the control you are getting the hdc of set to TRUE!
>
>True, but there's a more efficient way to do it
Okay, this one tickled the fancy. After a prolonged SmartCheck jam
session, here is what I observed VB doing with regard to graphics:
In VB5 SP2/3, for Forms, PictureBoxes, and UserControls (didn't
check PropertyPages, UserDocuments or any other new VB6
graphical control I don't yet know about, but I assume things will
be similar):
- when AutoRedraw is False, the hDC property returns the window's
real DC, and the CLS method is always just an UpdateWindow call.
- anytime the Image property is queried, or when AutoRedraw =
True and any graphics methods are preformed or the hDC property
is queried, VB creates another compatible memory DC and bitmap:
for Forms, the size of the screen; everything else is the size of the
respective window (note on the 1024x768 resolution and 16 bit
color I'm running here, a Form's Image equates to about a 1.5 MB
bitmap, or:
Call GetObject(obj.Image, Len(bm), bm)
With bm
Select Case .bmBitsPixel ' system color depth
Case 2: cb = (.bmWidth * .bmHeight) * (.bmPlanes / 4)
Case 4: cb = (.bmWidth * .bmHeight) * (.bmPlanes / 2)
Case 8: cb = (.bmWidth * .bmHeight) * .bmPlanes
Case 16: cb = (.bmWidth * .bmHeight) * (.bmPlanes * 2)
Case 24: cb = (.bmWidth * .bmHeight) * (.bmPlanes * 3)
Case 32: cb = (.bmWidth * .bmHeight) * (.bmPlanes * 4)
End Select
End With
(I think that's right...)
- the Image property always returns the memory bitmap handle.
- when AutoRedraw = True , hDC always returns the memory DC.
- after the memory bitmap is created, when AutoRedraw is set to
True, VB swaps all GDI objects from the window to the memory DC
and visa versa, when AutoRedraw = False, VB swaps all GDI objects
back to normal and StretchBlt the memory DC onto the form window
DC on each WM_PAINT.
- when AutoRedraw = True, CLS swaps the memory/window GDI
objects back to normal, deletes the memory DC and bitmap, and
we start all over.
- once the memory DC and bitmap are created, they live for the life
of the window, or until CLS is called.
- if the memory DC and bitmap were not created (Image = 0, don't
check it, including IntelliSense, or just watch your favorite memory
monitor), VB then does normal window painting on WM_PAINT.
Addendum: just ran a quick check on VB6/Win2K, and everything
seems about the same, though the memory hits from Image property
creation wasn't as pronounced (might be some kind of caching in
the OS or VB...).
So, with all that, and because we now know that VB suspends a
window's execution when it calls MsgBox, Raymond is either left
with subclassing the PictureBox and calling DrawEdge on each
WM_PAINT, or just setting the PictureBoxes AutoRedraw to true
calling DrawEdge once, and eating a few KBs...
Moral of the story: AutoRedraw isn't such a bad thing, but gets
worse with bigger windows.
--
Brad Martinez, http://www.mvps.org
Please direct questions/replies to the newsgroup
(just goes to show, you put a dangerous tool in the hands of an
insomniac and things get scary... :>)
Klaus H. Probst wrote in message <39125cb0@news.devx.com>...
>Raymond,
>
>True, but there's a more efficient way to do it, which is placing your
>drawing code in the Paint event of the control or form. Setting the
>AutoRedraw property to True will consume far more resources, since VB has to
>maintain an internal bitmap image of the object.
>
>BTW, in your Resize event, you'll need to add a call to InvalidateRect()
>passing a Null (zero) as the RECT and set the bErase argument to TRUE (1) in
>order for things to work, especially seeing that you're painting borders on
>the DC:
>
>Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long,
>lpRect As Any, ByVal bErase As Long) As Long
>
>Call InvalidateRect(UserControl.hWnd, ByVal 0&, 1)
>
>
>. . . . . . . . . . . . . . . . . . . . . .
>Klaus H. Probst, MVP
> http://www.vbbox.com/
> http://www.mvps.org/ccrp/
>
>Please post/reply to the newsgroup(s)
>
>
>"Raymond R Cassick" <raycass@adelphia.net> wrote in message
>news:39122fd3$1@news.devx.com...
>> I answered the question myself...
>>
>> If you want this to happen on an action like a Form_Load or a
>> UserControl_Resize, you MUST have the AutoRedraw proporty of the control
>you
>> are getting the hdc of set to TRUE!
>>
>> "Raymond R Cassick" <raycass@adelphia.net> wrote in message
>> news:39122d38@news.devx.com...
>> > Please tell me why the following code does nothing.. Place a picture box
>> on
>> > a usercontrol and name it picBackground. Paste this code into the
>> > usercontrol, then drop the control onto a form...
>> >
>> > Const BDR_RAISEDINNER = &H4
>> > Const BDR_RAISEDOUTER = &H1
>> >
>> > Const BF_BOTTOM = &H8
>> > Const BF_LEFT = &H1
>> > Const BF_RIGHT = &H4
>> > Const BF_TOP = &H2
>> > Const BF_TOPLEFT = (BF_TOP Or BF_LEFT)
>> > Const BF_BOTTOMRIGHT = (BF_BOTTOM Or BF_RIGHT)
>> >
>> >
>> > Private Sub UserControl_Resize()
>> >
>> > Dim di As Long
>> > Dim rc As RECT
>> >
>> > di = GetClientRect(picBackground.hwnd, rc)
>> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
>> > di = DrawEdge(picBackground.hDC, rc, BDR_RAISEDOUTER,
>BF_BOTTOMRIGHT)
>> >
>> > End Sub
>> >
>> > I am expecting the picture box to have a thin raise border around it. It
>> > ends up not having anything...
>> >
>> > Hmmm.. can anyone clue me in?
>> >
>> >
>> >
>>
>>
>
>
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks