Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The main thing you have to do is to disconnect your UI from your data set. I'd suggest that the way to do that is to put a layer in between. </p> <p>You will need to design a data structure of data cooked-for-display. This will most likely contain copies of some of your back-end data, but "cooked" to be easy to draw from. The key idea here is that this is quick and easy to paint from. You may even have this data structure contain calculated screen positions of bits of data so that it's quick to draw from. </p> <p>Whenever you get a WM_PAINT message you should get the most recent <em>complete</em> version of this structure and draw from it. If you do this properly, you should be able to handle multiple WM_PAINT messages per second because the paint code never refers to your back end data at all. It's just spinning through the cooked structure. The idea here is that its better to paint stale data quickly than to hang your UI. </p> <p>Meanwhile...</p> <p>You should have 2 complete copies of this cooked-for-display structure. One is what the WM_PAINT message looks at. (call it <b>cfd_A</b>) The other is what you hand to your CookDataForDisplay() function. (call it <b>cfd_B</b>). Your CookDataForDisplay() function runs in a separate thread, and works on building/updating <b>cfd_B</b> in the background. This function can take as long as it wants because it isn't interacting with the display in any way. Once the call returns <b>cfd_B</b> will be the most up-to-date version of the structure. </p> <p>Now swap <b>cfd_A</b> and <b>cfd_B</b> and InvalidateRect on your application window.</p> <p>A simplistic way to do this is to have your cooked-for-display structure be a bitmap, and that might be a good way to go to get the ball rolling, but I'm sure with a bit of thought you can do a much better job with a more sophisticated structure. </p> <p>So, referring back to your example. </p> <blockquote> <ul> <li>In the paint method, it will call a GetData method, often hundreds of times for hundreds of bits of data in one paint operation</li> </ul> </blockquote> <p>This is now 2 threads, the paint method refers to cfd_A and runs on the UI thread. Meanwhile cfd_B is being built by a background thread using GetData calls.</p> <p>The quick-and-dirty way to do this is</p> <ol> <li>Take your current WM_PAINT code, stick it into a function called PaintIntoBitmap(). </li> <li>Create a bitmap and a Memory DC, this is cfd_B.</li> <li>Create a thread and pass it cfd_B and have it call PaintIntoBitmap()</li> <li>When this thread completes, swap cfd_B and cfd_A</li> </ol> <p>Now your new WM_PAINT method just takes the pre-rendered bitmap in cfd_A and draws it to the screen. Your UI is now disconnnected from your backend GetData() function. </p> <p>Now the real work begins, because the quick-and-dirty way doesn't handle window resizing very well. You can go from there to refine what your cfd_A and cfd_B structures are a little at a time until you reach a point where you are satisfied with the result.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload