Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Issues with drawing on the HDC of QWidget by functions from other libs.
Forum Updated to NodeBB v4.3 + New Features

Issues with drawing on the HDC of QWidget by functions from other libs.

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 4 Posters 1.5k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • YurikaY Offline
    YurikaY Offline
    Yurika
    wrote on last edited by Yurika
    #1

    Hi,
    I'm very new to Qt and I'm trying to develop a medical image-processing program.

    The image load and displaying functions are provided by a 3rd-party lib. When I follow the tutorial on its website(https://www.leadtools.com/help/sdk/tutorials/cdll-load-display-and-save-images.html) to load and display images, everything works fine. So I then tried to reimplement its load and display images function on the Qt framework but I failed.

    Basically, the load image function is L_LoadBitmap and the displaying function is L_PaintDC. They both return SUCCESS when running but the image on my custom QWidget just failed to appear.

    L_PaintDC can display any image, at any size, to any device context(https://www.leadtools.com/help/sdk/main/api/l-paintdc.html). So I think the main task for me is to pass the correct HDC to this function. Since both of the core functions return SUCCESS but the image failed to appear, I guess it's probably because I passed a wrong HDC value to the L_PaintDC() function.

    Here are my core codes:

    VM_imagewindow* window = new VM_imagewindow(this, fileName);
    HWND hWnd = HWND((*window).winId());  //  Get this window's Handler
    HDC hdc = GetDC(hWnd);  //  Get the device context
    //  Define dst rectangle (LEADBmp is the loaded bitmap)
    RECT rc = { 0, 0, BITMAPWIDTH(&LEADBmp), BITMAPHEIGHT(&LEADBmp) }; 
    int i;  //  For debug
    if (LEADBmp.Flags.Allocated)
        //  Paint to DC. L_PaintDC returns 1 (SUCCESS) in this case
        i = L_PaintDC(hdc, &LEADBmp, NULL, NULL, &rc, NULL, SRCCOPY);
    window->setWindowFlag(Qt::Window);
    window->show();
    

    And here is the definition of my VM_imagewindow class:

    #pragma once
    
    #include <QWidget>
    #include "ui_VM_imagewindow.h"
    
    class VM_imagewindow : public QWidget, public Ui::VM_imagewindowClass
    {
    	Q_OBJECT
    
    public:
    	VM_imagewindow(QWidget *parent = nullptr);
    	VM_imagewindow(QWidget* parent, QString winTitle);
    	VM_imagewindow(QWidget* parent, QString winTitle, BITMAPHANDLE bitmap);
    	~VM_imagewindow();
    
    private:
    };
    

    I'm really not familiar with HDC and HWND such kinds of stuff.
    Can anyone find some clues? Thanks very much!

    Thanks for helping me.

    Pl45m4P 1 Reply Last reply
    0
    • YurikaY Yurika

      @Chris-Kawa Thank you a lot for telling me these. That's so enlightening!
      I'm a little frustrated knowing these since I'm literally neither an expert on Qt nor programming :( But I hope I can get over these.

      So in summary of your explanation, from my understanding, is there a way to disable Qt paint function and only apply the drawing function from the foreign API to paint the bitmap on QWidget's DC?

      Or as you said, I can create a bitmap to draw to and then wrap it in QImage. I can probably understand the principle but can you provide me more information about how can I create a bitmap and also get its DC to draw my target image using L_PaintDC function? Thank you!

      Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by Chris Kawa
      #12

      @Yurika said:

      is there a way to disable Qt paint function and only apply the drawing function from the foreign API to paint the bitmap on QWidget's DC

      You can use some flags when creating your widget, like Qt::WA_NoSystemBackground, to disable redrawing of the widget background, but this is a bit finicky and you'll get in trouble again when mixing this with e.g. child widgets, that draw on top of your widget.

      Using a bitmap buffer and drawing it in paint event is a bit more work (not that much), but assures it behaves correctly, as it's just native Qt painting in this case.

      As to how to do it - first make some variables in your class:

      HDC renderDC;
      HBITMAP renderBitmap;
      QImage renderImage;
      

      Then in your setup code (e.g. in constructor) create the bitmap, DC for it and the QImage wrapper:

      // Create a DC for rendering
      HDC displayDC = ::GetDC(NULL);
      renderDC = ::CreateCompatibleDC(displayDC);
      ::ReleaseDC(NULL, displayDC);
      
      // Create a bitmap buffer
      BITMAPINFO bmi {};
      bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
      bmi.bmiHeader.biWidth       = width;
      bmi.bmiHeader.biHeight      = -height; // yup, negative for top-down order
      bmi.bmiHeader.biPlanes      = 1;
      bmi.bmiHeader.biBitCount    = 32;
      bmi.bmiHeader.biCompression = BI_RGB;
      uchar* data = nullptr;
      renderBitmap = ::CreateDIBSection(renderDC, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&data), NULL, 0);
      
      // Create a Qt wrapper over the bitmap data
      renderImage = QImage(data, width, height, QImage::Format_RGB32);
      

      Don't forget to clean it up somewhere (e.g. in the destructor):

      ::DeleteObject(renderBitmap);
      ::DeleteDC(renderDC);
      

      and then you can use it in the paintEvent like this:

      HGDIOBJ prevObj = ::SelectObject(renderDC, renderBitmap);
      // Draw to renderDC using your foreign api here
      ::SelectObject(renderDC, prevObj);
      
      QPainter painter(this);
      painter.drawImage(0,0, renderImage);
      
      YurikaY 1 Reply Last reply
      3
      • YurikaY Yurika

        Hi,
        I'm very new to Qt and I'm trying to develop a medical image-processing program.

        The image load and displaying functions are provided by a 3rd-party lib. When I follow the tutorial on its website(https://www.leadtools.com/help/sdk/tutorials/cdll-load-display-and-save-images.html) to load and display images, everything works fine. So I then tried to reimplement its load and display images function on the Qt framework but I failed.

        Basically, the load image function is L_LoadBitmap and the displaying function is L_PaintDC. They both return SUCCESS when running but the image on my custom QWidget just failed to appear.

        L_PaintDC can display any image, at any size, to any device context(https://www.leadtools.com/help/sdk/main/api/l-paintdc.html). So I think the main task for me is to pass the correct HDC to this function. Since both of the core functions return SUCCESS but the image failed to appear, I guess it's probably because I passed a wrong HDC value to the L_PaintDC() function.

        Here are my core codes:

        VM_imagewindow* window = new VM_imagewindow(this, fileName);
        HWND hWnd = HWND((*window).winId());  //  Get this window's Handler
        HDC hdc = GetDC(hWnd);  //  Get the device context
        //  Define dst rectangle (LEADBmp is the loaded bitmap)
        RECT rc = { 0, 0, BITMAPWIDTH(&LEADBmp), BITMAPHEIGHT(&LEADBmp) }; 
        int i;  //  For debug
        if (LEADBmp.Flags.Allocated)
            //  Paint to DC. L_PaintDC returns 1 (SUCCESS) in this case
            i = L_PaintDC(hdc, &LEADBmp, NULL, NULL, &rc, NULL, SRCCOPY);
        window->setWindowFlag(Qt::Window);
        window->show();
        

        And here is the definition of my VM_imagewindow class:

        #pragma once
        
        #include <QWidget>
        #include "ui_VM_imagewindow.h"
        
        class VM_imagewindow : public QWidget, public Ui::VM_imagewindowClass
        {
        	Q_OBJECT
        
        public:
        	VM_imagewindow(QWidget *parent = nullptr);
        	VM_imagewindow(QWidget* parent, QString winTitle);
        	VM_imagewindow(QWidget* parent, QString winTitle, BITMAPHANDLE bitmap);
        	~VM_imagewindow();
        
        private:
        };
        

        I'm really not familiar with HDC and HWND such kinds of stuff.
        Can anyone find some clues? Thanks very much!

        Pl45m4P Offline
        Pl45m4P Offline
        Pl45m4
        wrote on last edited by
        #2

        @Yurika

        Debug your application and check what values you receive in the process.


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        Christian EhrlicherC YurikaY 2 Replies Last reply
        0
        • Pl45m4P Pl45m4

          @Yurika

          Debug your application and check what values you receive in the process.

          Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #3

          @Pl45m4 aYou should paint during QWidget::paintEvent(). Your widget is not even visible in your code above when you're executing L_PaintDC().

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          Pl45m4P 1 Reply Last reply
          3
          • Christian EhrlicherC Christian Ehrlicher

            @Pl45m4 aYou should paint during QWidget::paintEvent(). Your widget is not even visible in your code above when you're executing L_PaintDC().

            Pl45m4P Offline
            Pl45m4P Offline
            Pl45m4
            wrote on last edited by
            #4

            @Christian-Ehrlicher Why me? :D
            It's not my topic :)

            That would be the next thing I would have replied.
            The HWND / winID is used before the widget is shown, so it might even change and you're addressing an invalid window


            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            1 Reply Last reply
            1
            • Pl45m4P Pl45m4

              @Yurika

              Debug your application and check what values you receive in the process.

              YurikaY Offline
              YurikaY Offline
              Yurika
              wrote on last edited by
              #5

              @Christian-Ehrlicher @Pl45m4 OMG, thanks a lot for informing me of these! I've moved all of the L_PaintDC related codes into the paintEvent(QPaintEvent* e) function and it successfully displays the image.

              But there some new issues came out. When I drag or resize the window, the image sometimes flickers and sometimes disappears completely. And when I drag the window again, sometimes the image reappears. These also happen when I restore the window after minimizing it. Here is my new codes:

              Claim QPaintEvent override:

              protected:
              	void paintEvent(QPaintEvent* e) override;
              

              Definition:

              void VM_imagewindow::paintEvent(QPaintEvent* e)
              {
                  HWND hWnd = HWND(winId());  //  Get this window's Handler
                  HDC hdc = GetDC(hWnd);  //  Get the device context
                  RECT rc = { 0, 0, BITMAPWIDTH(&targetBitmap), BITMAPHEIGHT(&targetBitmap) };    //  Define dst rectangle
                  int i;  //  For debug
                  if (targetBitmap.Flags.Allocated)
                      //  L_PaintDC returns 1 in this case
                      i = L_PaintDC(hdc, &targetBitmap, NULL, NULL, &rc, NULL, SRCCOPY);
              }
              

              By the way, I'm actually using the QMdiArea and QMdiSubWindow which handles my VM_imagewindow because I want my software to be like photoshop.

              Is there anything I'm doing wrong?

              Thanks for helping me.

              Christian EhrlicherC Pl45m4P 2 Replies Last reply
              0
              • YurikaY Yurika

                @Christian-Ehrlicher @Pl45m4 OMG, thanks a lot for informing me of these! I've moved all of the L_PaintDC related codes into the paintEvent(QPaintEvent* e) function and it successfully displays the image.

                But there some new issues came out. When I drag or resize the window, the image sometimes flickers and sometimes disappears completely. And when I drag the window again, sometimes the image reappears. These also happen when I restore the window after minimizing it. Here is my new codes:

                Claim QPaintEvent override:

                protected:
                	void paintEvent(QPaintEvent* e) override;
                

                Definition:

                void VM_imagewindow::paintEvent(QPaintEvent* e)
                {
                    HWND hWnd = HWND(winId());  //  Get this window's Handler
                    HDC hdc = GetDC(hWnd);  //  Get the device context
                    RECT rc = { 0, 0, BITMAPWIDTH(&targetBitmap), BITMAPHEIGHT(&targetBitmap) };    //  Define dst rectangle
                    int i;  //  For debug
                    if (targetBitmap.Flags.Allocated)
                        //  L_PaintDC returns 1 in this case
                        i = L_PaintDC(hdc, &targetBitmap, NULL, NULL, &rc, NULL, SRCCOPY);
                }
                

                By the way, I'm actually using the QMdiArea and QMdiSubWindow which handles my VM_imagewindow because I want my software to be like photoshop.

                Is there anything I'm doing wrong?

                Christian EhrlicherC Online
                Christian EhrlicherC Online
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @Yurika said in Issues with drawing on the HDC of QWidget by functions from other libs.:

                (targetBitmap.Flags.Allocated)

                Is this always true after a resize?
                A resize/move event should trigger a repaint.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                YurikaY 1 Reply Last reply
                0
                • YurikaY Yurika

                  @Christian-Ehrlicher @Pl45m4 OMG, thanks a lot for informing me of these! I've moved all of the L_PaintDC related codes into the paintEvent(QPaintEvent* e) function and it successfully displays the image.

                  But there some new issues came out. When I drag or resize the window, the image sometimes flickers and sometimes disappears completely. And when I drag the window again, sometimes the image reappears. These also happen when I restore the window after minimizing it. Here is my new codes:

                  Claim QPaintEvent override:

                  protected:
                  	void paintEvent(QPaintEvent* e) override;
                  

                  Definition:

                  void VM_imagewindow::paintEvent(QPaintEvent* e)
                  {
                      HWND hWnd = HWND(winId());  //  Get this window's Handler
                      HDC hdc = GetDC(hWnd);  //  Get the device context
                      RECT rc = { 0, 0, BITMAPWIDTH(&targetBitmap), BITMAPHEIGHT(&targetBitmap) };    //  Define dst rectangle
                      int i;  //  For debug
                      if (targetBitmap.Flags.Allocated)
                          //  L_PaintDC returns 1 in this case
                          i = L_PaintDC(hdc, &targetBitmap, NULL, NULL, &rc, NULL, SRCCOPY);
                  }
                  

                  By the way, I'm actually using the QMdiArea and QMdiSubWindow which handles my VM_imagewindow because I want my software to be like photoshop.

                  Is there anything I'm doing wrong?

                  Pl45m4P Offline
                  Pl45m4P Offline
                  Pl45m4
                  wrote on last edited by
                  #7

                  @Yurika said in Issues with drawing on the HDC of QWidget by functions from other libs.:

                  But there some new issues came out. When I drag or resize the window, the image sometimes flickers and sometimes disappears completely. And when I drag the window again, sometimes the image reappears. These also happen when I restore the window after minimizing it.

                  This sounds like the behavior described in this topic here
                  @hskoglund 's answer there might work out for you:

                  • https://forum.qt.io/post/596932

                  If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                  ~E. W. Dijkstra

                  YurikaY 1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    @Yurika said in Issues with drawing on the HDC of QWidget by functions from other libs.:

                    (targetBitmap.Flags.Allocated)

                    Is this always true after a resize?
                    A resize/move event should trigger a repaint.

                    YurikaY Offline
                    YurikaY Offline
                    Yurika
                    wrote on last edited by
                    #8

                    @Christian-Ehrlicher Yes it is. Is repaint also a virtual function defined in QWidget? So did you mean I have to do something inside the repaint function?

                    Thanks for helping me.

                    1 Reply Last reply
                    0
                    • Pl45m4P Pl45m4

                      @Yurika said in Issues with drawing on the HDC of QWidget by functions from other libs.:

                      But there some new issues came out. When I drag or resize the window, the image sometimes flickers and sometimes disappears completely. And when I drag the window again, sometimes the image reappears. These also happen when I restore the window after minimizing it.

                      This sounds like the behavior described in this topic here
                      @hskoglund 's answer there might work out for you:

                      • https://forum.qt.io/post/596932
                      YurikaY Offline
                      YurikaY Offline
                      Yurika
                      wrote on last edited by
                      #9

                      @Pl45m4 I tried it but unfortunately it doesn't work.

                      Thanks for helping me.

                      1 Reply Last reply
                      0
                      • Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by Chris Kawa
                        #10

                        The "problem" here is that Qt painting, since 4.something is double buffered, meaning paintEvent does not paint directly onto the window DC, but to a backbuffer that is then BitBlt to the window.

                        This means that when you create another DC on the same surface you're basically racing with Qt as to who gets to paint last. It might look like something is working, but, as with any race, it's just a coincidence on your particular setup (Windows version, graphics adapter and driver etc. etc.). Might work for some static painting, but the timing changes slightly on resize and you get flicker. On other machine it might flicker in other scenarios, all the time even.

                        Qt does not expose a window DC that you can draw to, so the only way to do it in sync is to use Qt's drawing facilities i.e. draw using QPainter in paintEvent. Since you have a foreign API for drawing you can create a bitmap to draw to and then wrap it in QImage interface and paint to the window using one of the QPainter's functions. Just make sure that the bitmap and QImage have compatible data formats.

                        YurikaY 1 Reply Last reply
                        2
                        • Chris KawaC Chris Kawa

                          The "problem" here is that Qt painting, since 4.something is double buffered, meaning paintEvent does not paint directly onto the window DC, but to a backbuffer that is then BitBlt to the window.

                          This means that when you create another DC on the same surface you're basically racing with Qt as to who gets to paint last. It might look like something is working, but, as with any race, it's just a coincidence on your particular setup (Windows version, graphics adapter and driver etc. etc.). Might work for some static painting, but the timing changes slightly on resize and you get flicker. On other machine it might flicker in other scenarios, all the time even.

                          Qt does not expose a window DC that you can draw to, so the only way to do it in sync is to use Qt's drawing facilities i.e. draw using QPainter in paintEvent. Since you have a foreign API for drawing you can create a bitmap to draw to and then wrap it in QImage interface and paint to the window using one of the QPainter's functions. Just make sure that the bitmap and QImage have compatible data formats.

                          YurikaY Offline
                          YurikaY Offline
                          Yurika
                          wrote on last edited by
                          #11

                          @Chris-Kawa Thank you a lot for telling me these. That's so enlightening!
                          I'm a little frustrated knowing these since I'm literally neither an expert on Qt nor programming :( But I hope I can get over these.

                          So in summary of your explanation, from my understanding, is there a way to disable Qt paint function and only apply the drawing function from the foreign API to paint the bitmap on QWidget's DC?

                          Or as you said, I can create a bitmap to draw to and then wrap it in QImage. I can probably understand the principle but can you provide me more information about how can I create a bitmap and also get its DC to draw my target image using L_PaintDC function? Thank you!

                          Thanks for helping me.

                          Chris KawaC 1 Reply Last reply
                          0
                          • YurikaY Yurika

                            @Chris-Kawa Thank you a lot for telling me these. That's so enlightening!
                            I'm a little frustrated knowing these since I'm literally neither an expert on Qt nor programming :( But I hope I can get over these.

                            So in summary of your explanation, from my understanding, is there a way to disable Qt paint function and only apply the drawing function from the foreign API to paint the bitmap on QWidget's DC?

                            Or as you said, I can create a bitmap to draw to and then wrap it in QImage. I can probably understand the principle but can you provide me more information about how can I create a bitmap and also get its DC to draw my target image using L_PaintDC function? Thank you!

                            Chris KawaC Offline
                            Chris KawaC Offline
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on last edited by Chris Kawa
                            #12

                            @Yurika said:

                            is there a way to disable Qt paint function and only apply the drawing function from the foreign API to paint the bitmap on QWidget's DC

                            You can use some flags when creating your widget, like Qt::WA_NoSystemBackground, to disable redrawing of the widget background, but this is a bit finicky and you'll get in trouble again when mixing this with e.g. child widgets, that draw on top of your widget.

                            Using a bitmap buffer and drawing it in paint event is a bit more work (not that much), but assures it behaves correctly, as it's just native Qt painting in this case.

                            As to how to do it - first make some variables in your class:

                            HDC renderDC;
                            HBITMAP renderBitmap;
                            QImage renderImage;
                            

                            Then in your setup code (e.g. in constructor) create the bitmap, DC for it and the QImage wrapper:

                            // Create a DC for rendering
                            HDC displayDC = ::GetDC(NULL);
                            renderDC = ::CreateCompatibleDC(displayDC);
                            ::ReleaseDC(NULL, displayDC);
                            
                            // Create a bitmap buffer
                            BITMAPINFO bmi {};
                            bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
                            bmi.bmiHeader.biWidth       = width;
                            bmi.bmiHeader.biHeight      = -height; // yup, negative for top-down order
                            bmi.bmiHeader.biPlanes      = 1;
                            bmi.bmiHeader.biBitCount    = 32;
                            bmi.bmiHeader.biCompression = BI_RGB;
                            uchar* data = nullptr;
                            renderBitmap = ::CreateDIBSection(renderDC, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&data), NULL, 0);
                            
                            // Create a Qt wrapper over the bitmap data
                            renderImage = QImage(data, width, height, QImage::Format_RGB32);
                            

                            Don't forget to clean it up somewhere (e.g. in the destructor):

                            ::DeleteObject(renderBitmap);
                            ::DeleteDC(renderDC);
                            

                            and then you can use it in the paintEvent like this:

                            HGDIOBJ prevObj = ::SelectObject(renderDC, renderBitmap);
                            // Draw to renderDC using your foreign api here
                            ::SelectObject(renderDC, prevObj);
                            
                            QPainter painter(this);
                            painter.drawImage(0,0, renderImage);
                            
                            YurikaY 1 Reply Last reply
                            3
                            • Chris KawaC Chris Kawa

                              @Yurika said:

                              is there a way to disable Qt paint function and only apply the drawing function from the foreign API to paint the bitmap on QWidget's DC

                              You can use some flags when creating your widget, like Qt::WA_NoSystemBackground, to disable redrawing of the widget background, but this is a bit finicky and you'll get in trouble again when mixing this with e.g. child widgets, that draw on top of your widget.

                              Using a bitmap buffer and drawing it in paint event is a bit more work (not that much), but assures it behaves correctly, as it's just native Qt painting in this case.

                              As to how to do it - first make some variables in your class:

                              HDC renderDC;
                              HBITMAP renderBitmap;
                              QImage renderImage;
                              

                              Then in your setup code (e.g. in constructor) create the bitmap, DC for it and the QImage wrapper:

                              // Create a DC for rendering
                              HDC displayDC = ::GetDC(NULL);
                              renderDC = ::CreateCompatibleDC(displayDC);
                              ::ReleaseDC(NULL, displayDC);
                              
                              // Create a bitmap buffer
                              BITMAPINFO bmi {};
                              bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
                              bmi.bmiHeader.biWidth       = width;
                              bmi.bmiHeader.biHeight      = -height; // yup, negative for top-down order
                              bmi.bmiHeader.biPlanes      = 1;
                              bmi.bmiHeader.biBitCount    = 32;
                              bmi.bmiHeader.biCompression = BI_RGB;
                              uchar* data = nullptr;
                              renderBitmap = ::CreateDIBSection(renderDC, &bmi, DIB_RGB_COLORS, reinterpret_cast<void **>(&data), NULL, 0);
                              
                              // Create a Qt wrapper over the bitmap data
                              renderImage = QImage(data, width, height, QImage::Format_RGB32);
                              

                              Don't forget to clean it up somewhere (e.g. in the destructor):

                              ::DeleteObject(renderBitmap);
                              ::DeleteDC(renderDC);
                              

                              and then you can use it in the paintEvent like this:

                              HGDIOBJ prevObj = ::SelectObject(renderDC, renderBitmap);
                              // Draw to renderDC using your foreign api here
                              ::SelectObject(renderDC, prevObj);
                              
                              QPainter painter(this);
                              painter.drawImage(0,0, renderImage);
                              
                              YurikaY Offline
                              YurikaY Offline
                              Yurika
                              wrote on last edited by
                              #13

                              @Chris-Kawa I just tried this and it does work! No flicker anymore and everything seems to be fine! Thank you so much!

                              Just want to understand the mechanics behind these, can you explain a little bit about why do I have to create the bitmap buffer? What if I don't do this step?

                              Thanks for helping me.

                              Chris KawaC 1 Reply Last reply
                              0
                              • YurikaY Yurika has marked this topic as solved on
                              • YurikaY Yurika

                                @Chris-Kawa I just tried this and it does work! No flicker anymore and everything seems to be fine! Thank you so much!

                                Just want to understand the mechanics behind these, can you explain a little bit about why do I have to create the bitmap buffer? What if I don't do this step?

                                Chris KawaC Offline
                                Chris KawaC Offline
                                Chris Kawa
                                Lifetime Qt Champion
                                wrote on last edited by
                                #14

                                @Yurika Your foreign API draws to a DC and Qt doesn't expose the window DC that it uses to you. The code creates an intermediate buffer and then selects it in a DC that can draw to it. This basically lets your function draw to the buffer. Then a QImage wraps over the same buffer storage so that you can use Qt API (QPainter) to draw to the Qt's backbuffer.

                                So what happens is:

                                • Make a custom DC compatible with your display.
                                • Make a win32 DIB buffer.
                                • Make a QImage that shares the storage memory with the buffer (this means you can access the same buffer via win32 and Qt APIs).
                                • Select the buffer into the DC
                                • Draw to the DC (which effectively means to the buffer)
                                • Create a QPainter (Qt API that paints to the backbuffer)
                                • Draw the buffer as QImage to the Qt's backbuffer, which then will be blit to the window when appropriate (usually at monitor's V-Sync).

                                If your drawing function just paints a picture (HBITMAP) then you can skip the additional buffer and your L_PaintDC function and make the QImage wrapper directly over the source bitmap. The example I posted is just more generic and lets you do any type of painting to the DC.

                                YurikaY 1 Reply Last reply
                                3
                                • Chris KawaC Chris Kawa

                                  @Yurika Your foreign API draws to a DC and Qt doesn't expose the window DC that it uses to you. The code creates an intermediate buffer and then selects it in a DC that can draw to it. This basically lets your function draw to the buffer. Then a QImage wraps over the same buffer storage so that you can use Qt API (QPainter) to draw to the Qt's backbuffer.

                                  So what happens is:

                                  • Make a custom DC compatible with your display.
                                  • Make a win32 DIB buffer.
                                  • Make a QImage that shares the storage memory with the buffer (this means you can access the same buffer via win32 and Qt APIs).
                                  • Select the buffer into the DC
                                  • Draw to the DC (which effectively means to the buffer)
                                  • Create a QPainter (Qt API that paints to the backbuffer)
                                  • Draw the buffer as QImage to the Qt's backbuffer, which then will be blit to the window when appropriate (usually at monitor's V-Sync).

                                  If your drawing function just paints a picture (HBITMAP) then you can skip the additional buffer and your L_PaintDC function and make the QImage wrapper directly over the source bitmap. The example I posted is just more generic and lets you do any type of painting to the DC.

                                  YurikaY Offline
                                  YurikaY Offline
                                  Yurika
                                  wrote on last edited by
                                  #15

                                  @Chris-Kawa That makes sense. Thanks very much!

                                  Thanks for helping me.

                                  1 Reply Last reply
                                  0

                                  • Login

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • Users
                                  • Groups
                                  • Search
                                  • Get Qt Extensions
                                  • Unsolved