Results 1 to 15 of 15

Thread: Only for gurus!!!

Hybrid View

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2000
    Location
    New Delhi, India
    Posts
    75

    Only for gurus!!!

    My question is very straightforward.

    Is there any way to make the background of Richtextbox control transparent. Or is it possible at all?

  2. #2
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333
    Try setting its borderstyle to rtfNoBorder, and its backcolor to the same back color as your form.

  3. #3
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    You could subclass the RTFBox window and whenever you recieve a message WM_ERASEBKND you could send a WM_PRINTCLIENT message to the window below the rich text box to make it draw itself onto the rich text box's background.

    There are probably other ways - what, exactly, do you want to show through the rich text box?

    Hope this helps,
    Duncan
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  4. #4
    I'm about to be a PowerPoster! Hack's Avatar
    Join Date
    Aug 2001
    Location
    Searching for mendhak
    Posts
    58,333
    That sounds like an interesting solution MerrionComputin. How would you code that?

  5. #5
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    Bother - doesn't work...when you scroll the rich text box, the see through bit scrolls away which looks might weird.
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Jul 2000
    Location
    New Delhi, India
    Posts
    75
    I have a picture on my form. I want that this picture to be seen through the RichTextBox.

    MerrionComputin - I have no idea about subclassing. Could you please post a code snippet of the logic you have mentioned. Thanks for your response.

  7. #7
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    Subclassing 101
    (Note: some of the detail has been reduced for clarity)


    1. What is subclassing?
    Each and every window has a message queue and a message processing loop. During the normal course of operation the window takes one message off the queue, decides whether to process it or not, acts on the message and then moves on to the next message.
    For example, when you press a key while the focus is on the rich text box the operating system queues a WM_KEYDOWN a WM_KEYUP and a WM_CHAR message to the rich text box's message queue. The rich text box reads these off and decides whether the keypress causes it to change it's content (i.e. if it is a printable character). If so it adds the character to it's internal buffer, calculates where the character needs to be printed and sets that part of the window to be invalidated. This causes a WM_ERASEBKND and then a WM_PAINT message to be added to it's queue. In response to these it paints the update region with the defined background colour and then draws the character on top of it.
    Subclassing is writing your own procedure to handle these messages and instructing the window to use this. You can then alter the default behaviour that happens when a message occurs - in our example you can prevent the rich text box using the default colour to redraw the background and get it to use a copy of the underlying window instead. Those messages whose default behaviour is OK to you are simply passed on to the existing message handler to deal with.

    2. How is it done?
    What you have to do is write your window message handling proc to a predefined format and then get the address of this procedure and call the SetWindowLong API to set this to be the window's message handler. The defined format is:
    VB Code:
    1. Public gOldWndProc As Long
    2.  
    3. '\\ --[VB_WindowProc]--------------------------------------------------------
    4. '\\ 'typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
    5. '\\ Parameters:
    6. '\\   hwnd - window handle receiving message
    7. '\\   wMsg - The window message (WM_..etc.)
    8. '\\   wParam - First message parameter
    9. '\\   lParam - Second message parameter
    10. '\\ --------------------------------------------------------------------------------
    11. '\\ (c) 2001 - Merrion Computing.
    12. '\\ Please check [url]http://www.merrioncomputing.com[/url] for updates.
    13. '\\ --------------------------------------------------------------------------------
    14. Public Function VB_WindowProc(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    15.  
    16. '\\ Process the messages here
    17.  
    18. End Function
    19. [/code]
    20. Note that this proc must be defined as public and be in a [b].bas[/b] module.
    21. And the call (in the form load, usually) to set this to be your rich text box's message handker to it is:
    22. [code]
    23. Private Declare Function SetWindowLongApi Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    24. Private Const GWL_WNDPROC = (-4)
    25.  
    26. Private Sub Form_Load()
    27.     gOldWndProc = SetWindowLongApi(RichText1.hwnd, GWL_WNDPROC, AddressOf VB_WindowProc)
    28. End Sub

    ...to be continued...
    Last edited by MerrionComputin; Mar 26th, 2002 at 12:19 PM.
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  8. #8
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    3. Decoding the windows message
    There are a very large number of predefined window messages. The one we are interested in is WM_ERASEBKGND = &H14. However they each have very different parameter requirements - for example if you want to erase a background you only need to know the Device context that needs to be erased, whereas for a WM_CHAR message you need to know which character was pressed, the repetitions, the scan code etc. However there are only two parameters available for all this information to be passed - wParam and lParam. This means that the content of these two parameters depends on the type of message being sent....for WM_ERASEBKND the wParam member is zero always and the lParam member is a handle to the device context that needs to be erased.
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  9. #9
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    4. Passing the other messages on
    Since you don't really want to have to write the code for every single window message you need to delegate (pass on) those that you aren't interested in to the existing window procedure. You do this with the CallWindowProc API call...
    Code:
    Public gOldWndProc As Long
    
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    '\\ --[VB_WindowProc]--------------------------------------------------------
    '\\ 'typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
    '\\ Parameters:
    '\\   hwnd - window handle receiving message
    '\\   wMsg - The window message (WM_..etc.)
    '\\   wParam - First message parameter
    '\\   lParam - Second message parameter
    '\\ --------------------------------------------------------------------------------
    '\\ (c) 2001 - Merrion Computing. 
    '\\ Please check http://www.merrioncomputing.com for updates.
    '\\ --------------------------------------------------------------------------------
    Public Function VB_WindowProc(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    '\\ Process the messages here
    If msg = WM_ERASEBKND Then
       '\\ hDC is in lParam
    Else
         If gOldWndProc  = 0 Then
             VB_Windowproc = DefWindowProc(hWnd, uMsg, wParam, lParam)
        Else
             VB_Windowproc = CallWindowproc(gOldWndProc, hWnd, uMsg, wParam, lParam)
        End If
    End If
    
    End Function
    Last edited by MerrionComputin; Mar 26th, 2002 at 06:31 AM.
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  10. #10
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    5. Drawbacks
    The most obvious drawback in using subclassing is that any runtime error that occurs in a subclassing routine will crash the entire application. If you are in debug mode it will crash the debugger as well.
    Also in order to decode the wParam and lParam values you will need to know about things like memory addresses and bitwise comparisons and cutting long values into 4 bytes etc. that Visual basic doesn't usually involve.
    Thirdly the overhead of writing a new VB_Windowproc for each different subclassing operation you want to perform soon becomes mightily tedius.
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  11. #11
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    6. Shortcut to subclassing
    Fortunately a number of controls (including EventVB) exist that make this easier. To subclass the rich text box with the EventVB.dll :

    Code:
    '\\ In form
    Dim WithEvents vbLink As EventVB.ApiFunctions
    Dim WithEvents vbRTFWnd As EventVB.ApiWindow
    
    Private Sub Form_Load()
     
      Set vbLink = New EventVB.ApiFunctions
      
      Set vbRTFWnd = New EventVB.ApiWindow
      vbRtfWnd.hwnd = Me.RichTextbox1.hwnd
      '\\ Subclass the window
       vbLink.SubclassedWindows.Add vbRTFWnd
    
    End Sub
    
    
    Private Sub vbRTFWnd_WindowMessageFired(ByVal msg As WindowMessages,ByVal wParam As Long ,ByVal lParam As Long, Cancel As Boolean, ProcRet As Long)
    
    If msg = WM_ERASEBKND Then
        '\\ Prevent default processing
        Cancel = True
        ProcRet = 1
    End If
    
    End Sub
    HTH,
    Duncan
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  12. #12
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    ROFL

    Right - it turns out all that subclassing stuff isn't needed at all.

    The following (with EventVB) works:
    VB Code:
    1. Dim vbLink As EventVB.ApiFunctions
    2. Dim vbWndRtf As EventVB.ApiWindow
    3.  
    4. Private Sub Form_Load()
    5.  
    6. Set vbLink = New EventVB.ApiFunctions
    7.  
    8. Set vbWndRtf = New EventVB.ApiWindow
    9.  
    10. With vbWndRtf
    11.     .hwnd = RichText1.hwnd
    12.     .DeviceContext.Backstyle = TRANSPARENT
    13.     .SetWindowStyle WS_EX_TRANSPARENT, True
    14. End With
    15.  
    16. End Sub

    And it looks pretty smart - I think I'm gonna use this in some of my apps...

    HTH,
    Duncan
    Last edited by MerrionComputin; Apr 16th, 2002 at 07:55 AM.
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

  13. #13
    Fanatic Member MoMad's Avatar
    Join Date
    Oct 2000
    Location
    Seattle, WA
    Posts
    625
    Wow!!! That is one hell of a OCX!!! Very coool.

    I will take a look at it.
    :MoMad:
    Nice Sig!

    http://go.to/momad/ Status: Not Ready

  14. #14

    Thread Starter
    Lively Member
    Join Date
    Jul 2000
    Location
    New Delhi, India
    Posts
    75

    fantastic

    Hi MerrionComputin,

    Yo have really given me a fantastic start on whole stuff. thanks a heap. Franky I dont really like the idea of subclassing. It simple crashes your system for no reason. Do you have any idea why does it crash so often. Anyway keep posting your suggestions. I am really learning!!!

  15. #15
    Frenzied Member MerrionComputin's Avatar
    Join Date
    Apr 2001
    Location
    Dublin, Ireland
    Posts
    1,616
    Do you have any idea why does it crash so often.
    Subclassing doesn't crash all that often if you take care with it. The main thing is to make sure no run time errors occur in the subclassed part of the code as this will cause VB to exit. To do this, you absolutely must have Option Explicit specified everywhere and have
    VB Code:
    1. On Error Resume Next
    in your VB WndProc.

    If you are careful then the amazing capabilities exposed by subclassing are worth the risk. With EventVB this risk should be reduced anyway as there are many people using it so more sets of eyes catching any bugs...

    HTH,
    Duncan
    ----8<---------------------------------------
    NEW - The .NET printer queue monitor component
    ----8<---------------------------------------
    Now with Examples of use

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width