Replace Control's Device Context

Posted on 2004-10-04
Medium Priority
Last Modified: 2013-11-13

Is it possible to replace a Device Context (DC in the rest of the question) of some control with my own DC?
My intention is to make some control or window draw in memory, and not on screen.
After this is done, I would do some drawing on that image, and only then return the modified image to the screen.

I need something like this, becouse I'm drawing something to control's surface, but the control gets refreshed very often, so I have to repeat that drawing every time the control is refreshed.
This produces constant blinking of my drawing.
To avoid that, I thought maybe it's possible to refresh and redraw the complete control in memory, and paint the result on screen.

Is it possible?

P.S. Please note that I'm a VB6 programmer, and I know little about other languages. I asked this question here in general grogramming area, becouse I think if it can be done,
then it will probably be done with API's and API's are common to all programming languages.
Question by:dbrckovi
  • 5
  • 4
  • 2
LVL 55

Expert Comment

by:Ryan Chong
ID: 12215898

>>so I have to repeat that drawing every time the control is refreshed. This produces constant blinking of my drawing.
How about applying LockWindowUpdate just before and after your process of drawing the control?


Private Declare Function LockWindowUpdate Lib "user32" Alias "LockWindowUpdate" (ByVal hwndLock As Long) As Long

in your control update procedure:

LockWindowUpdate me.hwnd 'or try control.hwnd

'Your update process goes here..

LockWindowUpdate false 'release lock update

Will this works for your situation?
LVL 11

Author Comment

ID: 12216141

Thanks, but it's not working.

I'm trying to BitBlt a background to RichTextBox control using AND operator.

Here's my code:
 - create a Picture box, RichTextBox and a timer
 - assign some picture to picture box
 - paste this code:
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long

Private Const SRCAND = &H8800C6

Dim NewDC As Long
Dim RichTextBox1DC As Long

Private Sub Form_Load()
    Dim lPrevBMP As Long
    RichTextBox1DC = GetDC(RichTextBox1.hwnd)
    NewDC = CreateCompatibleDC(RichTextBox1DC)
    lPrevBMP = SelectObject(NewDC, Picture1.Picture.Handle)
    BitBlt RichTextBox1DC, 0, 0, Picture1.Width / Screen.TwipsPerPixelX, Picture1.Height / Screen.TwipsPerPixelY, NewDC, 0, 0, SRCAND

    Timer1.Interval = 100
End Sub

Private Sub RichTextBox1_Change()
    BitBlt RichTextBox1DC, 0, 0, Picture1.Width / Screen.TwipsPerPixelX, Picture1.Height / Screen.TwipsPerPixelY, NewDC, 0, 0, SRCAND
End Sub

Private Sub Timer1_Timer()
    If Len(RichTextBox1.Text) < 1000 Then
        RichTextBox1.Text = RichTextBox1.Text & "X                     "
        RichTextBox1.Text = ""
    End If
End Sub

If I ommit the Refresh line, BitBlt will "mix" with the image that was there before, but if I enable it, it blinks.
So I thought maybe I can refresh the control im memory, BitBlt the background there, and paint only the final result.

Please, don't look for some ActiveX controls which act like RichTextBox and suport background picture. This is not the purpose of my question.
The purpose is to add a background image to any control which normaly has white background, and black text.

Expert Comment

ID: 12217048
i think you have 2 ways to do that
1) in the paint event of the control add your code which draws
2) create a custom class for that component and override the paint method
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

LVL 55

Accepted Solution

Ryan Chong earned 1500 total points
ID: 12223774
LVL 11

Author Comment

ID: 12224619


1) In order for my method to work, the background has to be white. This means that, even if I put it in Paint event, the control has to refresh itself before I can call BitBlt.
2) How do I create a custom class for it? Note that I'm programming in VB6. (I know how to create a class, but I don't see how this can help)


It looks promissing, but it doesn't work. Even the demonstration project doesn't work.
It seems that author screwed up somewhere, becouse VB says SSubTimer6.EMsgResponse type is not defined, and SSubTimer6 class is supposed to be in SSubTmr6.dll file,
which I downloaded, registered, and included in te project.
However, in Object Browser I can see that everything exists.
LVL 55

Expert Comment

by:Ryan Chong
ID: 12224657
Hi dbrckovi,

I had tested out the example there, it works for me under WinXP Pro SP2 with VB6.

You may miss something out there? Not sure.. try follow the instructions there.

LVL 11

Author Comment

ID: 12224798
I probably missed something. I'll try to track down the problem.

Even if I don't make it work, this link contains tons of usefull code, and I'll give you some points for that.

In the meanwhile, I'll leave this question open if someone comes up with something.

I just can't let go of the idea that this can be done by manipulating control's DC in some way. :-)
I mean, in DOS, you could draw something completely in memory, and display only the result. (Maybe DOS is not the best OS for comparing with Windows, but it makes sense)
I think there has to be something similar in Windows.

Ok. If this is not possible than can you explain to me why the following doesn't work?

I've red that every DC is made of few objects which define it's behaviour. Some of them are Bitmap, Text, Brush, Pen etc.
To assign some object to a DC, we use SelectObject API.

Then why doesn't this work:?
lPrevBMP = SelectObject(RichTextBox1DC, Picture1.Picture.Handle)             '(return value is 0)

Why does it work with NewDC, and not with RichTextBox1DC?
Note that NewDC is created using :        NewDC = CreateCompatibleDC(RichTextBox1DC)

If both DC's are compatible, then why does it work with one, but doesn't with another?
LVL 55

Expert Comment

by:Ryan Chong
ID: 12224848
I tested your code, ya, it did blinking on GUI.. i did try to amend your code but no luck so far, hmm...

Expert Comment

ID: 12246578
i dont know if it works in VB6
but in .NET you can declare a class to inherit a certain control.
i.e. class myCustomButton : Button
    protected override Paint( ..parameters..)
      //draw the control
LVL 11

Author Comment

ID: 12246709
I've never done anything similar in VB6, and I wouldn't surprise if it wasn't possible.

Although, I might be wrong. (Just becouse I didn't have contact with it, doesn't mean that it's impossible)

LVL 11

Author Comment

ID: 12285955
I managed to make it work under VB6 IDE. I don't know what I was missing, but it just worked at one point.
Yesterday night we lost power so my comp got restarted after few weeks of working, and I think this was the reason why it suddenly worked.

Method is still not perfect, but it gives me a lot of code to learn from, and that's why I'm accepting your answer.


Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
The SignAloud Glove is capable of translating American Sign Language signs into text and audio.
Simple Linear Regression
Six Sigma Control Plans

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question