flickerfix.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <windows.h>
  2. #include "ml.h"
  3. #include "../nu/CGlobalAtom.h"
  4. #ifndef LONGX86
  5. #ifdef _WIN64
  6. #define LONGX86 LONG_PTR
  7. #else /*_WIN64*/
  8. #define LONGX86 LONG
  9. #endif /*_WIN64*/
  10. #endif // LONGX86
  11. static CGlobalAtom PROP_FLIKERFIX(L"WAFFIX");
  12. typedef struct _FFDATA
  13. {
  14. WNDPROC oldProc;
  15. DWORD mode;
  16. BOOL unicode;
  17. BOOL forward;
  18. }FFDATA, *PFFDATA;
  19. static LRESULT WINAPI FlickerFixWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  20. {
  21. PFFDATA pfd;
  22. pfd = (PFFDATA)GetPropW(hwnd, PROP_FLIKERFIX);
  23. if (!pfd) return (IsWindowUnicode(hwnd)) ? DefWindowProcW(hwnd, uMsg, wParam, lParam) : DefWindowProcA(hwnd, uMsg, wParam, lParam);
  24. switch(uMsg)
  25. {
  26. case WM_ERASEBKGND:
  27. if (pfd->forward) break;
  28. if (FFM_NOERASE & pfd->mode) return 1;
  29. if (FFM_ERASEINPAINT & pfd->mode) return 0;
  30. if (FFM_FORCEERASE & pfd->mode)
  31. {
  32. HBRUSH hb;
  33. RECT rc;
  34. hb = CreateSolidBrush(pfd->mode & 0x00FFFFFF);
  35. GetClientRect(hwnd, &rc);
  36. FillRect((HDC)wParam, &rc, hb);
  37. DeleteObject(hb);
  38. return 1;
  39. }
  40. // otherwise unsubclass....
  41. case WM_NCDESTROY:
  42. if (FlickerFixWndProc == (WNDPROC)(LONG_PTR)GetWindowLongPtrW(hwnd, GWLP_WNDPROC))
  43. {
  44. RemovePropW(hwnd, PROP_FLIKERFIX);
  45. SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)pfd->oldProc);
  46. (pfd->unicode) ? CallWindowProcW(pfd->oldProc, hwnd, uMsg, wParam, lParam) :
  47. CallWindowProcA(pfd->oldProc, hwnd, uMsg, wParam, lParam);
  48. free(pfd);
  49. return 0;
  50. }
  51. else pfd->forward = TRUE;
  52. break;
  53. }
  54. return (pfd->unicode) ? CallWindowProcW(pfd->oldProc, hwnd, uMsg, wParam, lParam) :
  55. CallWindowProcA(pfd->oldProc, hwnd, uMsg, wParam, lParam);
  56. }
  57. BOOL FlickerFixWindow(HWND hwnd, INT mode)
  58. {
  59. PFFDATA pfd;
  60. if (!hwnd || !IsWindow(hwnd)) return FALSE;
  61. pfd = (PFFDATA)GetPropW(hwnd, PROP_FLIKERFIX);
  62. if (pfd) pfd->mode = mode;
  63. else
  64. {
  65. pfd = (PFFDATA)calloc(1, sizeof(FFDATA));
  66. if (pfd)
  67. {
  68. pfd->forward = FALSE;
  69. pfd->mode = mode;
  70. pfd->unicode = IsWindowUnicode(hwnd);
  71. pfd->oldProc = (WNDPROC)(LONG_PTR) ((pfd->unicode) ? SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)FlickerFixWndProc) :
  72. SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)FlickerFixWndProc));
  73. if (!pfd->oldProc || !SetPropW(hwnd, PROP_FLIKERFIX, pfd))
  74. {
  75. if (pfd->oldProc)
  76. {
  77. ((pfd->unicode) ? SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)pfd->oldProc) :
  78. SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)pfd->oldProc));
  79. }
  80. free(pfd);
  81. pfd = NULL;
  82. }
  83. }
  84. }
  85. return (NULL != pfd);
  86. }