Solved

Replace Control's Device Context

Posted on 2004-10-04
11
264 Views
Last Modified: 2013-11-13
Hi!

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.
0
Comment
Question by:dbrckovi
  • 5
  • 4
  • 2
11 Comments
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 12215898
Hi,

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

like:

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?
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12216141
Hi!

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
   
    Me.Show
    DoEvents
   
    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()
    RichTextBox1.Refresh
    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                     "
    Else
        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.

P.S.
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.
0
 
LVL 3

Expert Comment

by:IceColdas
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
0
 
LVL 49

Accepted Solution

by:
Ryan Chong earned 500 total points
ID: 12223774
0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12224619
Hi!

IceColads:

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)

ryancys:

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.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 49

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.

regards
0
 
LVL 11

Author Comment

by:dbrckovi
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?
0
 
LVL 49

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...
0
 
LVL 3

Expert Comment

by:IceColdas
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
   }
}
0
 
LVL 11

Author Comment

by:dbrckovi
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)

0
 
LVL 11

Author Comment

by:dbrckovi
ID: 12285955
OK.
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.

Thanks.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
A short article about a problem I had getting the GPS LocationListener working.
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 …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

757 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now