Replace Control's Device Context

Posted on 2004-10-04
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 50

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
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

LVL 50

Accepted Solution

Ryan Chong earned 500 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 50

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 50

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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

790 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