dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: [RESOLVED] Edit Control and text with transparent background scroll issue

  1. #1
    Join Date
    Feb 2012
    Location
    Italy
    Posts
    9

    [RESOLVED] Edit Control and text with transparent background scroll issue

    Hallo Everybody,
    need some help as I can't figoure out how to solve this problem:
    I've a edit control setted as multiline, autovscroll etc, and by WM_CTLCOLOREDIT I'm able to set a black background and a text color with transparent background. The issue comes in when i fill te edit with some text out of te edit window, and exactly when i scroll with the scroll bar cursor the text draws on top of itself and creates garbage like the attache picture.
    I've solved partially the issue subclassing the edit and perform a ShowWindow(hwnd, SW_HIDE) with sequentially ShowWindow(hwnd, SW_SHOW) when the left mouse button (WM_LBUTTONDOWN) is pushed on the scroll cursor (that trough a Timer Procedure)
    But this does not solve completely the issue, the "Ghost" text is still there for some milliseconds.
    Sorry for my bad english.
    Here's my full code:

    Code:
    #include <windows.h>
    
    #define IDC_EDIT 101
    
    LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    LRESULT APIENTRY EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    VOID CALLBACK ProceduraTimer(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime);
    
    //Puntatore a WindowProcedure originale
    //(variabile globale);
    WNDPROC wpOrigWindowProc = 0;
    
    
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 
        LPSTR lpCmdLine, int nCmdShow)
    {
      HWND hwnd;
      MSG  msg ;    
      WNDCLASS wc = {0};
      wc.lpszClassName = TEXT("GroupBox");
      wc.hInstance     = hInstance ;
      wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
      wc.lpfnWndProc   = WndProc ;
      wc.hCursor       = LoadCursor(0,IDC_ARROW);
    
      HINSTANCE g_hinst = hInstance;
      
      RegisterClass(&wc);
      hwnd = CreateWindow(wc.lpszClassName, TEXT("GroupBox"),
                          WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                          600, 200, 400, 450, 0, 0, hInstance, 0);  
                          
      while(GetMessage(&msg, NULL, 0, 0)) {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
      }
      return (int)msg.wParam;
    }
    
    LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
      HWND hwndEdit;
      DWORD CtrlEsitoID;
      HFONT hFont;
      HBRUSH hBrushCtrlBG;
      HDC hdcEdit;
      HWND hwndFocus = 0;
      HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
    
      switch(msg)  
      {
          
          case WM_CREATE:
               
                  hwndEdit = CreateWindow(TEXT("Edit"), NULL,
                                WS_TABSTOP | WS_CHILD | WS_VISIBLE | ES_WANTRETURN | WS_BORDER | 
                                WS_CLIPCHILDREN | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL,
                                10, 10, 360, 340, hwnd, (HMENU)IDC_EDIT, 0, 0);
                                
                                
                  //Installazione del Subclassing del controllo edit (registriamo
                  //il valore della Window Procedure precedente);
                  wpOrigWindowProc = (WNDPROC)SetWindowLong(hwndEdit, GWL_WNDPROC, 
                                                           (LONG)EditSubclassProc);
                  
                  hFont = CreateFont(10, 10, 0, 0, FW_EXTRALIGHT, FALSE, FALSE, FALSE, 
                                      DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, 
                                      CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
                                      DEFAULT_PITCH, "MS Sans Serif");
                                      
                  SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont, 0); 
                  break;
    
    
          case WM_COMMAND:
                  if((HIWORD(wParam) == BN_PUSHED)) {            
                                    SetTimer(hwnd, LOWORD(wParam), 200, ProceduraTimer);
    							}
                  if(HIWORD(wParam) == BN_UNPUSHED) {
                                    KillTimer(hwnd,HIWORD(wParam));
                                    ShowWindow((HWND)lParam, SW_HIDE);
                                    UpdateWindow((HWND)lParam);
                                    ShowWindow((HWND)lParam,SW_SHOW);
    							}
                  break;
    
    
          case WM_DESTROY:
                  //Rimuovo il subclass dal controllo edit
                  SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG)wpOrigWindowProc);
                  PostQuitMessage(0);
                  break; 
                
                  
          case WM_CTLCOLOREDIT:
                  CtrlEsitoID = GetDlgCtrlID((HWND)lParam);
                  if (CtrlEsitoID == IDC_EDIT)  {
                      hBrushCtrlBG = CreateSolidBrush(RGB(0, 0, 0));
                      hdcEdit = (HDC)wParam;
                      SetTextColor(hdcEdit, RGB(71, 239, 235));
                      //SetBkColor(hdcEdit, RGB(0, 0, 0));
                      SetBkMode(hdcEdit, TRANSPARENT);
                      return (LONG)hBrushCtrlBG;  
                  }
                  break;
                  
           case WM_LBUTTONDOWN: 
                  //if(wParam == MK_LBUTTON)
                  break; 
                    
      }
      return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    
    //Procedura di Subclass
    LRESULT APIENTRY EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        UINT code = 0;
        switch(uMsg)  {
               case WM_LBUTTONDOWN: code = BN_PUSHED; break;
               case WM_LBUTTONUP:   code = BN_UNPUSHED; break;
        }
        if(code)
               SendMessage(GetParent(hwnd), WM_COMMAND, 
                          MAKELONG(GetDlgCtrlID(hwnd), code), 
                          (LPARAM)hwnd);
        if(wpOrigWindowProc)
               return CallWindowProc(wpOrigWindowProc, hwnd, uMsg, wParam, lParam);
        return 0;
    }
    
    VOID CALLBACK ProceduraTimer(HWND hwnd, UINT msg, UINT idEvent, DWORD dwTime)
    {
       HWND hwndCtrl = GetDlgItem(hwnd, idEvent);
       ShowWindow(hwndCtrl, SW_HIDE);
       UpdateWindow(hwndCtrl);
       ShowWindow(hwndCtrl,SW_SHOW); 
    }
    Any help is very very appreciated, i'm trying to solve this frmo 3 days.
    Thank's in advance.
    Attached Images Attached Images  
    Last edited by ovidiucucu; February 15th, 2012 at 08:33 AM.

  2. #2
    Join Date
    Feb 2012
    Location
    Italy
    Posts
    9

    Re: Edit Control and text with transparent background scroll issue

    Sorry for the wrong code insertion, I can't edit it.

  3. #3
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,602

    Re: Edit Control and text with transparent background scroll issue

    hBrushCtrlBG = CreateSolidBrush(RGB(0, 0, 0));
    You constantly create the brush, but never destroy it. This is gonna exhaust GDI objects. You may need stock object instead:
    Code:
    hBrushCtrlBG = (HBRUSH)GetStockObject(BLACK_BRUSH);
    Otherwise you need to create the brash beforehand, and return it always when you need the solid brush.
    Best regards,
    Igor

  4. #4
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,602

    Re: Edit Control and text with transparent background scroll issue

    Well, basically transparent background is the mistake that causes all the fuzz.

    Code:
          case WM_CTLCOLOREDIT:
                  CtrlEsitoID = GetDlgCtrlID((HWND)lParam);
                  if (CtrlEsitoID == IDC_EDIT)  {
                      hdcEdit = (HDC)wParam;
                      SetTextColor(hdcEdit, RGB(71, 239, 235));
                      SetBkColor(hdcEdit, RGB(0, 0, 0));
                      //SetBkMode(hdcEdit, TRANSPARENT);
                      return (LONG)GetStockObject(BLACK_BRUSH);  
                  }
    Last edited by Igor Vartanov; February 15th, 2012 at 01:35 PM.
    Best regards,
    Igor

  5. #5
    Join Date
    Feb 2012
    Location
    Italy
    Posts
    9

    Re: Edit Control and text with transparent background scroll issue

    Hallo, Mr. Igor, Thank you so much for your replay.
    I Already Knew how to solve by the setBkcolor instead and i'm Sorry for
    My inexact explanation: I need to learn how to solve with a transparent background if for exemple i want to set a background Image in a control and scroll the text over it.
    Can you please explain me better the solution you tell before, i mean that one using the stock object instead the brush one. I'm going crazy (I'm learning Win API from less than two mounth) Thank you so much

  6. #6
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,602

    Re: Edit Control and text with transparent background scroll issue

    Regarding the solution for transparent background, I have no one. Per my experience nobody in sane mind fights with old style Windows controls like button, edit box, combo box or list box. It's always easier to implement yourself all what you need rather than tweak the standard control to something beyond its pre-designed behavior.

    The first my message was not a solution at all. It was just a remark regarding the problem you might still be unaware of. When you create your custom GDI object, you need to destroy the one symmetrically. The issue is very similar to memory allocation, and in fact it actually is, as GDI object is allocated by kernel for your process. Naturally, there is a limit for a number of GDI objects created by a process, and once you've lost control on creating ones, sooner or later your process exhausts allowed resources, after then you app behavior becomes unpredictable.

    Unlike to process' custom GDI objects, there in kernel a number of stock objects exist, that are kinda "statically" allocated, and therefore, never cause exhausting. You just request the ones from kernel and never bother about deallocating those. The BLACK_BRUSH is one of them.
    Last edited by Igor Vartanov; February 16th, 2012 at 08:10 AM.
    Best regards,
    Igor

  7. #7
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,207

    Re: Edit Control and text with transparent background scroll issue

    The common edit control is a simple one, designed to simply display an editable text, with no special effects like background images.
    As Igor already stated, a good aproach is to make a custom control from scratch.

    However, this is a frequently asked question, including in this forum.
    I have found a simple solution: post a custom message from WM_VSCROLL, WM_HSCROLL and WM_MOUSEWHEEL handlers, then call RedrawWindow.

    See attached example, containing a "transparent" multiline edit control with no "fuzzy" scroll effects.
    Attached Files Attached Files
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,602

    Re: Edit Control and text with transparent background scroll issue

    Thanks, Ovidiu, this really works. As far as I understand, handling WM_ERASEBKGND is another vital part of the solution.
    Best regards,
    Igor

  9. #9
    Join Date
    Feb 2012
    Location
    Italy
    Posts
    9

    Re: Edit Control and text with transparent background scroll issue

    Thanks both Mr. Igor and Mr. Ovidiucucu for our kind replay.
    To answer to Mr. Igor I would like to say that I'm fighting against my problem only to learn the principal raw API functions and use them with C language. If mine is a wrong approach, I'm cheerely to learn also more useful technics to programming on windows, by the way I don't know how to creat something wich is not a standard control.
    Thank you also for your Partecipation Mr. Ovidiucucu. As soon as I go back home I study the source you've kindly posted.
    I will be really grateful for any hint you can give to me.
    Sorry again for my english.
    Thank you in advance.
    Last edited by rebeldevil; February 16th, 2012 at 07:28 PM.

  10. #10
    Join Date
    Feb 2012
    Location
    Italy
    Posts
    9

    Thumbs up Re: Edit Control and text with transparent background scroll issue

    Thank you very much Mr. Ovidiucucu,
    the attached sample is exactly the solution to my problem. Now I'm studying some statement in your source wich I really have difficulty to understand. For example the purpose of the WM_ONERASEBKGND message and its relating handle function(the use of patblt function, for example).
    Otherwise I understand enough the subclassing of the edit control, the "hook" of the WM_VSCROLL etc. messages, and the redrawwindow function as well. But I'm helping myself with the MSDN documentation and so I think everything should go well.
    Thank you a very very lot.
    I serched for a solution on the web and have spent a lot time for that job. Thank you again

  11. #11
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,207

    Re: Edit Control and text with transparent background scroll issue

    Well, I've painted the dialog's background under WM_ERASEBKGND because old habits... You can do more complex drawing there and the window can be not a dialog.
    However, if the only one purpose is to paint the dialog's background using whatever brush (probably, the most common case) it's easier to just handle WM_CTLCOLORDLG.

    So, you can modify the demo code as follows:
    Code:
    BOOL CALLBACK MainDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    
       switch(uMsg)
       {
          HANDLE_MSG(hWnd, WM_INITDIALOG, MainDialog_OnInitDialog);
          HANDLE_MSG(hWnd, WM_COMMAND, MainDialog_OnCommand);
          HANDLE_MSG(hWnd, WM_CTLCOLOREDIT, MainDialog_OnCtlColor);
          HANDLE_MSG(hWnd, WM_CTLCOLORDLG, MainDialog_OnCtlColor); // <-- add this
          // HANDLE_MSG(hWnd, WM_ERASEBKGND, MainDialog_OnEraseBkgnd); // <-- remove this
          HANDLE_MSG(hWnd, WM_DESTROY, MainDialog_OnDestroy);
       }
       return FALSE;
    }
    Code:
    HBRUSH MainDialog_OnCtlColor(HWND hWnd, HDC hDC, HWND hWndChild, int type)
    {
       HBRUSH hBrush = NULL;
       switch(type)
       {
       case CTLCOLOR_EDIT:
          ::SetTextColor(hDC, RGB(0,0,128));
          ::SetBkMode(hDC, TRANSPARENT);
          hBrush = g_hBrushBack;
          break;
       case CTLCOLOR_DLG: // <-- add this
          hBrush = g_hBrushBack;
          break;
       }
       return hBrush;
    }
    Also, remove MainDialog_OnEraseBkgnd function declaration and definition; don't need them anymore.

    PatBlt function basically paints in a device context by using the selected brush.
    More details about it can be found in MSDN Library: http://msdn.microsoft.com/en-us/libr...(v=VS.85).aspx

    Also, you've probably noticed "weird" macros like HANDLE_MSG. They are "message crackers", defined in <windowsx.h> and are very helpful to save a lot of code (+ time = money ) when handle messages in window procedures.

    If any other problem/question, do not hesitate to ask.
    Last edited by ovidiucucu; February 17th, 2012 at 03:17 AM.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

  12. #12
    Join Date
    Feb 2012
    Location
    Italy
    Posts
    9

    Re: Edit Control and text with transparent background scroll issue

    Thank you again Mr. Ovidiucucu,
    Your explanation is now enough bright, I'm going to make some experiment to try the behavior of the various functions.

    Let me take advantage of your patient please, I've also two other really important questions about I hadn't find yet an answer on the web:

    1. Build custom controls from scrath, as Mr. Igor tell me in a previuos post, is that possible only by MFC or .NET or something like those or can I do that also with raw API functions?

    2. This is the more important: when I would write a little and simple application, what must I consider wheter choose to write a dialog based application or a window one (I mean with window procedure, WM_CREATE, etc)? I read something on MSDN but nothing is so really clear to my.

    Thank you again for you kindly patience and for the time you are wasting to help me.

  13. #13
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,207

    Re: Edit Control and text with transparent background scroll issue

    1. MFC is a framework, having a C++ library built over Windows API and intended to make Windows programmers' life much easier. So, there is nothing that can be made using MFC and cannot be done using raw-WinAPI.
    The problem is the required effort. For an example, I first tested your problem in a simple dialog-based MFC application and that took me less than five minutes. After that, I did the same with above posted raw-WinAPI demo project and sweat about one hour.
    Make yourself the difference.

    There is no problem in writing a custom control from scratch using raw-WinAPI. Basically, it's a child window of a given custom window class. You can even place it in a dialog template (see "Custom Control" in Controls toolbox) then type its window class name in the proprieties. Of course, you have to register the window class yourself. This is all for the beginning... more sweat is coming further...

    If you reffer to ActiveX controls, this is more complicated and I cannot even dare to think about making something like that without MFC or ATL framework support.

    2. Initially, the dialogs were designed as temporary windows and not as main application windows. However, IMO there is nothing wrong to make even serious applications dialog-based. I made it myself. At last, dialogs are also windows, of a particular window class, but windows.
    Depends on what you want to accomplish.


    3. (additional) I'm just curious, what do you think is wrong with MFC?
    Last edited by ovidiucucu; February 17th, 2012 at 07:07 AM.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: http://codexpert.ro/blog/author/ovidiu-cucu/

  14. #14
    Join Date
    Feb 2012
    Location
    Italy
    Posts
    9

    Smile Re: Edit Control and text with transparent background scroll issue

    Hi Mr.Ovidiucucu,
    Thank you again for your constant presence.
    "Message Crackers" are Ok for me, I've studied them with no difficult.
    Now I'm trying to convert your code in a window based application (window procedure and subclassing), just to learn from myself mistakes, and I was able to figure out a version with solid brush background(black) but not yet with a bitmap background. But It seems that I'm to so far from my goal.

    Dialog-based or window application is now a clear concept form me. Thank you.

    For the addition [number 3 :-) ], I don't mean that there is something wrong with MFC, te only reason of my question is that I began to study C as first programming language, now I've a good control of it. So I decide to learn to program GUI on windows and so I've found some good tutorial on the web, wich explain the Win32 Api using C language ( there does not exhist in my country a book (even in english language)), so I must study on material that I find on the net.
    That enjoy me a lot (win API + C) and when I undefeated the first time with the word "MFC" (reading websites) I've realised that there aren't guides on the net. So I choose to learn Api first, a little, then study c++ and then to begin something more recent (like MFC).
    Your explanation about MFC bring me to understand the difference.

    But I'm thinking if you are so king to post me the MFC code of the transparent_edit_demo, I sure will be able to start from that to begin study basilar MFC, if you are agree.

    Thank you a lot

  15. #15
    Join Date
    Feb 2012
    Location
    Italy
    Posts
    9

    Unhappy Re: Edit Control and text with transparent background scroll issue

    Hallo again, please help me, I can't figure out how implement your code in a Window procedure instead a dialog one, Mr. Ovidiucucu.
    Should i manage WM_PAINT message?

Page 1 of 2 12 LastLast

Posting Permissions

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


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)