dcsimg


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Page 3 of 3 FirstFirst 123
Results 31 to 43 of 43

Thread: GetClientRect and DrawEdge not working on a UserControl?

  1. #31
    Klaus H. Probst Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Hi Michael,

    > >Once you compile your app that goes away (well, in most cases).

    >
    > Hmmm, interesting, I did not know that. Maybe it is not so useless after
    > all. When does it not work when compiled?


    When you do it incorrectly ;-)
    As far as I can tell, it never fails to work.

    > >But what's that have to do with the original posting?

    >
    > It was in relation to you post.


    Oh, OK.


    .. . . . . . . . . . . . . . . . . . . . . .
    Klaus H. Probst, MVP
    http://www.vbbox.com/
    http://www.mvps.org/ccrp/

    Please post/reply to the newsgroup(s)




  2. #32
    Klaus H. Probst Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Hi Brad,

    > [less gdi memory hit on VB6/Win2K]
    > >More efficient GDI code? Maybe....

    >
    > I really couldn't say, or didn't look hard enough. But seeing
    > as how any given bitmap should occupy the same amount
    > of memory on any given OS, something's definitely going on...


    Hmmm... interesting. Maybe an uninteded side effect of the new OS.

    > >> 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...

    > >
    > >Brad, does the MessageBox problem go away once you're out of the IDE? I
    > >think it does, doesn't it?

    >
    > D'oh, it sure does. In the compile MsgBox doles out to
    > MessageBoxIndirect, which itself installs a WH_MSGFILTER
    > hook (more SC :>). I guess VB just blocks events from being
    > raised in the IDE during the MsgBox call...


    Phew! :-)

    > >Isn't this the same contention issue as the
    > >timers?

    >
    > That they fire in the compiled binary during MsgBox? Yes.
    > Another little interesting tidbit, when VB starts its Timer,
    > it specifies the window's handle in which the Timer is sited
    > for SetTimer's nIDEvent param, i.e.
    >
    > SetTimer(Form1.hWnd, Form1.hWnd, Timer1.Interval, 0)
    >
    > Also, in VB's Form1 wndproc, VB does a KillTimer before
    > raising the Timer event, then does SetTimer again. ...just
    > in case you ever need to futz with WM_TIMER in your
    > wndprocs... :-)


    Wow :-) Seems VB does a lot of unecessary stuff. I mean, it's like the
    re-setting of an MDI form's styles every time it gets a WM_SIZE. Uncanny :-)

    > >> (just goes to show, you put a dangerous tool in the hands of an
    > >> insomniac and things get scary... :>)

    > >
    > >You can say that again <g>

    >
    > Hey, now what is that supposed to mean? :-)


    Er, nothing <g>

    > >But great info on the innards of veebee there, sir. Appreciated ;-)

    >
    > Thanks man, it wouldn't be so much fun if VB didn't hide all
    > this stuff. :-)


    You'd have to sleep, and that'd be no fun :-)


    ____________
    Klaus




  3. #33
    Klaus H. Probst Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Hi Brad,

    > [less gdi memory hit on VB6/Win2K]
    > >More efficient GDI code? Maybe....

    >
    > I really couldn't say, or didn't look hard enough. But seeing
    > as how any given bitmap should occupy the same amount
    > of memory on any given OS, something's definitely going on...


    Hmmm... interesting. Maybe an uninteded side effect of the new OS.

    > >> 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...

    > >
    > >Brad, does the MessageBox problem go away once you're out of the IDE? I
    > >think it does, doesn't it?

    >
    > D'oh, it sure does. In the compile MsgBox doles out to
    > MessageBoxIndirect, which itself installs a WH_MSGFILTER
    > hook (more SC :>). I guess VB just blocks events from being
    > raised in the IDE during the MsgBox call...


    Phew! :-)

    > >Isn't this the same contention issue as the
    > >timers?

    >
    > That they fire in the compiled binary during MsgBox? Yes.
    > Another little interesting tidbit, when VB starts its Timer,
    > it specifies the window's handle in which the Timer is sited
    > for SetTimer's nIDEvent param, i.e.
    >
    > SetTimer(Form1.hWnd, Form1.hWnd, Timer1.Interval, 0)
    >
    > Also, in VB's Form1 wndproc, VB does a KillTimer before
    > raising the Timer event, then does SetTimer again. ...just
    > in case you ever need to futz with WM_TIMER in your
    > wndprocs... :-)


    Wow :-) Seems VB does a lot of unecessary stuff. I mean, it's like the
    re-setting of an MDI form's styles every time it gets a WM_SIZE. Uncanny :-)

    > >> (just goes to show, you put a dangerous tool in the hands of an
    > >> insomniac and things get scary... :>)

    > >
    > >You can say that again <g>

    >
    > Hey, now what is that supposed to mean? :-)


    Er, nothing <g>

    > >But great info on the innards of veebee there, sir. Appreciated ;-)

    >
    > Thanks man, it wouldn't be so much fun if VB didn't hide all
    > this stuff. :-)


    You'd have to sleep, and that'd be no fun :-)


    ____________
    Klaus




  4. #34
    Karl E. Peterson Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Hi Klaus / Brad --

    > > Also, in VB's Form1 wndproc, VB does a KillTimer before
    > > raising the Timer event, then does SetTimer again. ...just
    > > in case you ever need to futz with WM_TIMER in your
    > > wndprocs... :-)

    >
    > Wow :-) Seems VB does a lot of unecessary stuff.


    Having written a timer, lemme tell ya -- there's hardly any unnecessary protections
    unwarranted when it comes to the *crazy* stuff folks do in Timer events! I can
    easily see why they do this. It is really interesting that they felt *that*
    defensive, though!

    Later... Karl




  5. #35
    Karl E. Peterson Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Hi Klaus / Brad --

    > > Also, in VB's Form1 wndproc, VB does a KillTimer before
    > > raising the Timer event, then does SetTimer again. ...just
    > > in case you ever need to futz with WM_TIMER in your
    > > wndprocs... :-)

    >
    > Wow :-) Seems VB does a lot of unecessary stuff.


    Having written a timer, lemme tell ya -- there's hardly any unnecessary protections
    unwarranted when it comes to the *crazy* stuff folks do in Timer events! I can
    easily see why they do this. It is really interesting that they felt *that*
    defensive, though!

    Later... Karl




  6. #36
    Raymond R Cassick Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Changing the code to read this does however work fine...


    Private Sub DrawBorder(ctlControl As Control)

    Dim RetVal As Long
    Dim AreaRc As RECT

    ctlControl.Refresh
    RetVal = GetClientRect(ctlControl.hWnd, AreaRc)
    RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDINNER, BF_TOPLEFT)
    RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDOUTER,
    BF_BOTTOMRIGHT)

    End Sub

    My question here now is, how big of a hit am I taking on resources given the
    fact that I am using the AutoRedraw set to True? The area that I am
    refreshing is relatively small, so I would think that refreshing only causes
    the bitmap that has been saved by the AutoRedraw property to be redrawn
    again. I am also assuming that every time the object is drawn, the
    AutoRedraw property saves a new copy of the bitmap and throws out the old
    one. Am I assuming correctly? Or am I responsible for cleanup of the old
    bitmap?



    "Klaus H. Probst" <kprobst@vbbox.com> wrote in message
    news:39179c11@news.devx.com...
    > Raymond,
    >
    > You have to call InvalidateRect _in the Resize event_. That will trigger a
    > Paint event. From there you call your drawing code.
    >
    >
    > --
    > . . . . . . . . . . . . . . . . . . . . . .
    > 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:39177fcd@news.devx.com...
    > > Ok why does this code not do what it is supposed to then...

    >
    >
    >




  7. #37
    Raymond R Cassick Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Changing the code to read this does however work fine...


    Private Sub DrawBorder(ctlControl As Control)

    Dim RetVal As Long
    Dim AreaRc As RECT

    ctlControl.Refresh
    RetVal = GetClientRect(ctlControl.hWnd, AreaRc)
    RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDINNER, BF_TOPLEFT)
    RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDOUTER,
    BF_BOTTOMRIGHT)

    End Sub

    My question here now is, how big of a hit am I taking on resources given the
    fact that I am using the AutoRedraw set to True? The area that I am
    refreshing is relatively small, so I would think that refreshing only causes
    the bitmap that has been saved by the AutoRedraw property to be redrawn
    again. I am also assuming that every time the object is drawn, the
    AutoRedraw property saves a new copy of the bitmap and throws out the old
    one. Am I assuming correctly? Or am I responsible for cleanup of the old
    bitmap?



    "Klaus H. Probst" <kprobst@vbbox.com> wrote in message
    news:39179c11@news.devx.com...
    > Raymond,
    >
    > You have to call InvalidateRect _in the Resize event_. That will trigger a
    > Paint event. From there you call your drawing code.
    >
    >
    > --
    > . . . . . . . . . . . . . . . . . . . . . .
    > 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:39177fcd@news.devx.com...
    > > Ok why does this code not do what it is supposed to then...

    >
    >
    >




  8. #38
    Klaus H. Probst Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Hi Raymond,

    > Changing the code to read this does however work fine...
    >
    >
    > Private Sub DrawBorder(ctlControl As Control)
    >
    > Dim RetVal As Long
    > Dim AreaRc As RECT
    >
    > ctlControl.Refresh
    > RetVal = GetClientRect(ctlControl.hWnd, AreaRc)
    > RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDINNER, BF_TOPLEFT)
    > RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDOUTER,
    > BF_BOTTOMRIGHT)
    >
    > End Sub


    If you're calling this proc from the Paint even then you're generating
    _another_ paint event by using the Refresh method (well, at least in most
    situations -- Refresh calls UpdateWindow and UpdateWindow doesn't always
    cause the DC to become invalidated). Is there any reason why you don't want
    to use InvalidateRect??

    > My question here now is, how big of a hit am I taking on resources given

    the
    > fact that I am using the AutoRedraw set to True? The area that I am
    > refreshing is relatively small, so I would think that refreshing only

    causes
    > the bitmap that has been saved by the AutoRedraw property to be redrawn
    > again. I am also assuming that every time the object is drawn, the
    > AutoRedraw property saves a new copy of the bitmap and throws out the old
    > one. Am I assuming correctly? Or am I responsible for cleanup of the old
    > bitmap?


    You are correct in that you are taking a hit. You are correct also in that
    the hit you're taking is relative to the size of the area that needs to be
    kept in memory, which determines the size of the bitmap. As to how the whole
    process works, see Brad's post on this same thread, which pretty much
    fleshes out what VB is doing behind the scenes. Then decide whether that
    looks better than just using InvalidateRect once in your Resize event. And
    no, you are not responsible for any GDI objects maintained internally by VB.
    Those are the runtime's responsibility.

    .. . . . . . . . . . . . . . . . . . . . . .
    Klaus H. Probst, MVP
    http://www.vbbox.com/
    http://www.mvps.org/ccrp/

    Please post/reply to the newsgroup(s)








  9. #39
    Klaus H. Probst Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Hi Raymond,

    > Changing the code to read this does however work fine...
    >
    >
    > Private Sub DrawBorder(ctlControl As Control)
    >
    > Dim RetVal As Long
    > Dim AreaRc As RECT
    >
    > ctlControl.Refresh
    > RetVal = GetClientRect(ctlControl.hWnd, AreaRc)
    > RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDINNER, BF_TOPLEFT)
    > RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDOUTER,
    > BF_BOTTOMRIGHT)
    >
    > End Sub


    If you're calling this proc from the Paint even then you're generating
    _another_ paint event by using the Refresh method (well, at least in most
    situations -- Refresh calls UpdateWindow and UpdateWindow doesn't always
    cause the DC to become invalidated). Is there any reason why you don't want
    to use InvalidateRect??

    > My question here now is, how big of a hit am I taking on resources given

    the
    > fact that I am using the AutoRedraw set to True? The area that I am
    > refreshing is relatively small, so I would think that refreshing only

    causes
    > the bitmap that has been saved by the AutoRedraw property to be redrawn
    > again. I am also assuming that every time the object is drawn, the
    > AutoRedraw property saves a new copy of the bitmap and throws out the old
    > one. Am I assuming correctly? Or am I responsible for cleanup of the old
    > bitmap?


    You are correct in that you are taking a hit. You are correct also in that
    the hit you're taking is relative to the size of the area that needs to be
    kept in memory, which determines the size of the bitmap. As to how the whole
    process works, see Brad's post on this same thread, which pretty much
    fleshes out what VB is doing behind the scenes. Then decide whether that
    looks better than just using InvalidateRect once in your Resize event. And
    no, you are not responsible for any GDI objects maintained internally by VB.
    Those are the runtime's responsibility.

    .. . . . . . . . . . . . . . . . . . . . . .
    Klaus H. Probst, MVP
    http://www.vbbox.com/
    http://www.mvps.org/ccrp/

    Please post/reply to the newsgroup(s)








  10. #40
    Brad Martinez Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Klaus/Raymond,

    I was going to go into another long diatribe with even more VB
    internal stuff, and about how it's probably easiest to let VB maintain
    a persistent bitmap of the DrawEdge (in the UserControl's Resize
    event set the PictureBox's AutoRedraw = True, erase previous
    DrawEdge with either PictureBox.Cls or FillRect, DrawEdge again,
    set AutoRedraw = False), but then I played a little with Klaus' idea,
    and low and behold something worked...

    Private Sub UserControl_Paint()
    Dim rc As RECT

    With Picture1
    Call GetClientRect(.hWnd, rc)

    ' must first erase previous DrawEdge, UpdateWindow is
    ' necessary so that the PictureBox's paint processing is
    ' completed before DrawEdge is called again...
    Call InvalidateRect(.hWnd, rc, 1)
    Call UpdateWindow(.hWnd)

    Call DrawEdge(.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
    Call DrawEdge(.hDC, rc, BDR_RAISEDOUTER, BF_BOTTOMRIGHT)
    End With

    End Sub

    That's all that's needed, no AutoRedraw (in fact is must be False,
    and the PictureBox must not be maintaining a persistent bitmap),
    no InvalidateRect in UserControl_Resize (what, and WM_PAINT
    won't happen after a WM_RESIZE anyway? :>). Though being
    limited to the PictureBox getting the DrawEdge only when the
    UserControl gets a WM_PAINT (and subsequently raising its Paint
    event, which is implementation specific anyway), it still is pretty
    darned efficient, and definitely opens up some new vistas here...

    Brad


    Klaus H. Probst wrote in message <3918ee86$1@news.devx.com>...
    >Hi Raymond,
    >
    >> Changing the code to read this does however work fine...
    >>
    >>
    >> Private Sub DrawBorder(ctlControl As Control)
    >>
    >> Dim RetVal As Long
    >> Dim AreaRc As RECT
    >>
    >> ctlControl.Refresh
    >> RetVal = GetClientRect(ctlControl.hWnd, AreaRc)
    >> RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDINNER, BF_TOPLEFT)
    >> RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDOUTER,
    >> BF_BOTTOMRIGHT)
    >>
    >> End Sub

    >
    >If you're calling this proc from the Paint even then you're generating
    >_another_ paint event by using the Refresh method (well, at least in most
    >situations -- Refresh calls UpdateWindow and UpdateWindow doesn't always
    >cause the DC to become invalidated). Is there any reason why you don't want
    >to use InvalidateRect??
    >
    >> My question here now is, how big of a hit am I taking on resources given

    >the
    >> fact that I am using the AutoRedraw set to True? The area that I am
    >> refreshing is relatively small, so I would think that refreshing only

    >causes
    >> the bitmap that has been saved by the AutoRedraw property to be redrawn
    >> again. I am also assuming that every time the object is drawn, the
    >> AutoRedraw property saves a new copy of the bitmap and throws out the old
    >> one. Am I assuming correctly? Or am I responsible for cleanup of the old
    >> bitmap?

    >
    >You are correct in that you are taking a hit. You are correct also in that
    >the hit you're taking is relative to the size of the area that needs to be
    >kept in memory, which determines the size of the bitmap. As to how the whole
    >process works, see Brad's post on this same thread, which pretty much
    >fleshes out what VB is doing behind the scenes. Then decide whether that
    >looks better than just using InvalidateRect once in your Resize event. And
    >no, you are not responsible for any GDI objects maintained internally by VB.
    >Those are the runtime's responsibility.
    >
    >. . . . . . . . . . . . . . . . . . . . . .
    >Klaus H. Probst, MVP
    > http://www.vbbox.com/
    > http://www.mvps.org/ccrp/
    >
    >Please post/reply to the newsgroup(s)







  11. #41
    Brad Martinez Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Klaus/Raymond,

    I was going to go into another long diatribe with even more VB
    internal stuff, and about how it's probably easiest to let VB maintain
    a persistent bitmap of the DrawEdge (in the UserControl's Resize
    event set the PictureBox's AutoRedraw = True, erase previous
    DrawEdge with either PictureBox.Cls or FillRect, DrawEdge again,
    set AutoRedraw = False), but then I played a little with Klaus' idea,
    and low and behold something worked...

    Private Sub UserControl_Paint()
    Dim rc As RECT

    With Picture1
    Call GetClientRect(.hWnd, rc)

    ' must first erase previous DrawEdge, UpdateWindow is
    ' necessary so that the PictureBox's paint processing is
    ' completed before DrawEdge is called again...
    Call InvalidateRect(.hWnd, rc, 1)
    Call UpdateWindow(.hWnd)

    Call DrawEdge(.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
    Call DrawEdge(.hDC, rc, BDR_RAISEDOUTER, BF_BOTTOMRIGHT)
    End With

    End Sub

    That's all that's needed, no AutoRedraw (in fact is must be False,
    and the PictureBox must not be maintaining a persistent bitmap),
    no InvalidateRect in UserControl_Resize (what, and WM_PAINT
    won't happen after a WM_RESIZE anyway? :>). Though being
    limited to the PictureBox getting the DrawEdge only when the
    UserControl gets a WM_PAINT (and subsequently raising its Paint
    event, which is implementation specific anyway), it still is pretty
    darned efficient, and definitely opens up some new vistas here...

    Brad


    Klaus H. Probst wrote in message <3918ee86$1@news.devx.com>...
    >Hi Raymond,
    >
    >> Changing the code to read this does however work fine...
    >>
    >>
    >> Private Sub DrawBorder(ctlControl As Control)
    >>
    >> Dim RetVal As Long
    >> Dim AreaRc As RECT
    >>
    >> ctlControl.Refresh
    >> RetVal = GetClientRect(ctlControl.hWnd, AreaRc)
    >> RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDINNER, BF_TOPLEFT)
    >> RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDOUTER,
    >> BF_BOTTOMRIGHT)
    >>
    >> End Sub

    >
    >If you're calling this proc from the Paint even then you're generating
    >_another_ paint event by using the Refresh method (well, at least in most
    >situations -- Refresh calls UpdateWindow and UpdateWindow doesn't always
    >cause the DC to become invalidated). Is there any reason why you don't want
    >to use InvalidateRect??
    >
    >> My question here now is, how big of a hit am I taking on resources given

    >the
    >> fact that I am using the AutoRedraw set to True? The area that I am
    >> refreshing is relatively small, so I would think that refreshing only

    >causes
    >> the bitmap that has been saved by the AutoRedraw property to be redrawn
    >> again. I am also assuming that every time the object is drawn, the
    >> AutoRedraw property saves a new copy of the bitmap and throws out the old
    >> one. Am I assuming correctly? Or am I responsible for cleanup of the old
    >> bitmap?

    >
    >You are correct in that you are taking a hit. You are correct also in that
    >the hit you're taking is relative to the size of the area that needs to be
    >kept in memory, which determines the size of the bitmap. As to how the whole
    >process works, see Brad's post on this same thread, which pretty much
    >fleshes out what VB is doing behind the scenes. Then decide whether that
    >looks better than just using InvalidateRect once in your Resize event. And
    >no, you are not responsible for any GDI objects maintained internally by VB.
    >Those are the runtime's responsibility.
    >
    >. . . . . . . . . . . . . . . . . . . . . .
    >Klaus H. Probst, MVP
    > http://www.vbbox.com/
    > http://www.mvps.org/ccrp/
    >
    >Please post/reply to the newsgroup(s)







  12. #42
    Raymond R Cassick Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Bravo! This works great! I ran 10000 interations of my roiutine and never
    saw a large draw on resources, at all, and it does look more efficient.

    I am going to make the changes to the OutlookNOte sample that I downloaded
    from Klaus's website yesterday.

    This API stuff is great!

    "Brad Martinez" <btmtz@msn.com.nospam> wrote in message
    news:3919c3b0@news.devx.com...
    > Klaus/Raymond,
    >
    > I was going to go into another long diatribe with even more VB
    > internal stuff, and about how it's probably easiest to let VB maintain
    > a persistent bitmap of the DrawEdge (in the UserControl's Resize
    > event set the PictureBox's AutoRedraw = True, erase previous
    > DrawEdge with either PictureBox.Cls or FillRect, DrawEdge again,
    > set AutoRedraw = False), but then I played a little with Klaus' idea,
    > and low and behold something worked...
    >
    > Private Sub UserControl_Paint()
    > Dim rc As RECT
    >
    > With Picture1
    > Call GetClientRect(.hWnd, rc)
    >
    > ' must first erase previous DrawEdge, UpdateWindow is
    > ' necessary so that the PictureBox's paint processing is
    > ' completed before DrawEdge is called again...
    > Call InvalidateRect(.hWnd, rc, 1)
    > Call UpdateWindow(.hWnd)
    >
    > Call DrawEdge(.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
    > Call DrawEdge(.hDC, rc, BDR_RAISEDOUTER, BF_BOTTOMRIGHT)
    > End With
    >
    > End Sub
    >
    > That's all that's needed, no AutoRedraw (in fact is must be False,
    > and the PictureBox must not be maintaining a persistent bitmap),
    > no InvalidateRect in UserControl_Resize (what, and WM_PAINT
    > won't happen after a WM_RESIZE anyway? :>). Though being
    > limited to the PictureBox getting the DrawEdge only when the
    > UserControl gets a WM_PAINT (and subsequently raising its Paint
    > event, which is implementation specific anyway), it still is pretty
    > darned efficient, and definitely opens up some new vistas here...
    >
    > Brad
    >
    >
    > Klaus H. Probst wrote in message <3918ee86$1@news.devx.com>...
    > >Hi Raymond,
    > >
    > >> Changing the code to read this does however work fine...
    > >>
    > >>
    > >> Private Sub DrawBorder(ctlControl As Control)
    > >>
    > >> Dim RetVal As Long
    > >> Dim AreaRc As RECT
    > >>
    > >> ctlControl.Refresh
    > >> RetVal = GetClientRect(ctlControl.hWnd, AreaRc)
    > >> RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDINNER,

    BF_TOPLEFT)
    > >> RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDOUTER,
    > >> BF_BOTTOMRIGHT)
    > >>
    > >> End Sub

    > >
    > >If you're calling this proc from the Paint even then you're generating
    > >_another_ paint event by using the Refresh method (well, at least in most
    > >situations -- Refresh calls UpdateWindow and UpdateWindow doesn't always
    > >cause the DC to become invalidated). Is there any reason why you don't

    want
    > >to use InvalidateRect??
    > >
    > >> My question here now is, how big of a hit am I taking on resources

    given
    > >the
    > >> fact that I am using the AutoRedraw set to True? The area that I am
    > >> refreshing is relatively small, so I would think that refreshing only

    > >causes
    > >> the bitmap that has been saved by the AutoRedraw property to be redrawn
    > >> again. I am also assuming that every time the object is drawn, the
    > >> AutoRedraw property saves a new copy of the bitmap and throws out the

    old
    > >> one. Am I assuming correctly? Or am I responsible for cleanup of the

    old
    > >> bitmap?

    > >
    > >You are correct in that you are taking a hit. You are correct also in

    that
    > >the hit you're taking is relative to the size of the area that needs to

    be
    > >kept in memory, which determines the size of the bitmap. As to how the

    whole
    > >process works, see Brad's post on this same thread, which pretty much
    > >fleshes out what VB is doing behind the scenes. Then decide whether that
    > >looks better than just using InvalidateRect once in your Resize event.

    And
    > >no, you are not responsible for any GDI objects maintained internally by

    VB.
    > >Those are the runtime's responsibility.
    > >
    > >. . . . . . . . . . . . . . . . . . . . . .
    > >Klaus H. Probst, MVP
    > > http://www.vbbox.com/
    > > http://www.mvps.org/ccrp/
    > >
    > >Please post/reply to the newsgroup(s)

    >
    >
    >
    >
    >




  13. #43
    Raymond R Cassick Guest

    Re: GetClientRect and DrawEdge not working on a UserControl?

    Bravo! This works great! I ran 10000 interations of my roiutine and never
    saw a large draw on resources, at all, and it does look more efficient.

    I am going to make the changes to the OutlookNOte sample that I downloaded
    from Klaus's website yesterday.

    This API stuff is great!

    "Brad Martinez" <btmtz@msn.com.nospam> wrote in message
    news:3919c3b0@news.devx.com...
    > Klaus/Raymond,
    >
    > I was going to go into another long diatribe with even more VB
    > internal stuff, and about how it's probably easiest to let VB maintain
    > a persistent bitmap of the DrawEdge (in the UserControl's Resize
    > event set the PictureBox's AutoRedraw = True, erase previous
    > DrawEdge with either PictureBox.Cls or FillRect, DrawEdge again,
    > set AutoRedraw = False), but then I played a little with Klaus' idea,
    > and low and behold something worked...
    >
    > Private Sub UserControl_Paint()
    > Dim rc As RECT
    >
    > With Picture1
    > Call GetClientRect(.hWnd, rc)
    >
    > ' must first erase previous DrawEdge, UpdateWindow is
    > ' necessary so that the PictureBox's paint processing is
    > ' completed before DrawEdge is called again...
    > Call InvalidateRect(.hWnd, rc, 1)
    > Call UpdateWindow(.hWnd)
    >
    > Call DrawEdge(.hDC, rc, BDR_RAISEDINNER, BF_TOPLEFT)
    > Call DrawEdge(.hDC, rc, BDR_RAISEDOUTER, BF_BOTTOMRIGHT)
    > End With
    >
    > End Sub
    >
    > That's all that's needed, no AutoRedraw (in fact is must be False,
    > and the PictureBox must not be maintaining a persistent bitmap),
    > no InvalidateRect in UserControl_Resize (what, and WM_PAINT
    > won't happen after a WM_RESIZE anyway? :>). Though being
    > limited to the PictureBox getting the DrawEdge only when the
    > UserControl gets a WM_PAINT (and subsequently raising its Paint
    > event, which is implementation specific anyway), it still is pretty
    > darned efficient, and definitely opens up some new vistas here...
    >
    > Brad
    >
    >
    > Klaus H. Probst wrote in message <3918ee86$1@news.devx.com>...
    > >Hi Raymond,
    > >
    > >> Changing the code to read this does however work fine...
    > >>
    > >>
    > >> Private Sub DrawBorder(ctlControl As Control)
    > >>
    > >> Dim RetVal As Long
    > >> Dim AreaRc As RECT
    > >>
    > >> ctlControl.Refresh
    > >> RetVal = GetClientRect(ctlControl.hWnd, AreaRc)
    > >> RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDINNER,

    BF_TOPLEFT)
    > >> RetVal = DrawEdge(ctlControl.hdc, AreaRc, BDR_RAISEDOUTER,
    > >> BF_BOTTOMRIGHT)
    > >>
    > >> End Sub

    > >
    > >If you're calling this proc from the Paint even then you're generating
    > >_another_ paint event by using the Refresh method (well, at least in most
    > >situations -- Refresh calls UpdateWindow and UpdateWindow doesn't always
    > >cause the DC to become invalidated). Is there any reason why you don't

    want
    > >to use InvalidateRect??
    > >
    > >> My question here now is, how big of a hit am I taking on resources

    given
    > >the
    > >> fact that I am using the AutoRedraw set to True? The area that I am
    > >> refreshing is relatively small, so I would think that refreshing only

    > >causes
    > >> the bitmap that has been saved by the AutoRedraw property to be redrawn
    > >> again. I am also assuming that every time the object is drawn, the
    > >> AutoRedraw property saves a new copy of the bitmap and throws out the

    old
    > >> one. Am I assuming correctly? Or am I responsible for cleanup of the

    old
    > >> bitmap?

    > >
    > >You are correct in that you are taking a hit. You are correct also in

    that
    > >the hit you're taking is relative to the size of the area that needs to

    be
    > >kept in memory, which determines the size of the bitmap. As to how the

    whole
    > >process works, see Brad's post on this same thread, which pretty much
    > >fleshes out what VB is doing behind the scenes. Then decide whether that
    > >looks better than just using InvalidateRect once in your Resize event.

    And
    > >no, you are not responsible for any GDI objects maintained internally by

    VB.
    > >Those are the runtime's responsibility.
    > >
    > >. . . . . . . . . . . . . . . . . . . . . .
    > >Klaus H. Probst, MVP
    > > http://www.vbbox.com/
    > > http://www.mvps.org/ccrp/
    > >
    > >Please post/reply to the newsgroup(s)

    >
    >
    >
    >
    >




Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center