рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реАрдбрд┐рдпреЛ рдкреНрд▓реЗрдпрд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдФрд░ рдпрд╣ рдХрд╛рд░реНрдп рдХреЗ рджреМрд░рд╛рди рдереЛрдбрд╝реА рджреЗрд░ рдХреЗ рд▓рд┐рдП "рд▓рдЯрдХрд╛" - рдХреНрдпреВрдЯреА рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЦрд┐рд▓рд╛рдбрд╝реА рдореЗрдВ рд╡реАрдбрд┐рдпреЛ рдЭрдкрдХреА рд▓реЗрдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИ рдФрд░ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ (рд╡реАрдбрд┐рдпреЛ рджреЗрдЦреЗрдВ)ред
QWidget рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ :: QWidget рд╕реЗ рдкрд╣рд▓реЗ (https://qt-project.org/doc/qt-4.8/qwidget.html#autoFillBackground -prop) рдореЗрдВ рдХреНрдпреВрдЯреА рднрд░ рдЬрд╛рдиреЗ рдХреЗ рдХрд╛рд░рдг рдкреЗрдВрдЯреЗрд╡реЗрдВрдЯ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред
WM_PAINT рдФрд░ WM_ERASEBACKGOUND рдХреЛ QWidget рдореЗрдВ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ :: winEvent рднреА рд╡рд┐рдлрд▓ рд░рд╣рд╛, рдХреНрдпреЛрдВрдХрд┐ рдкреЗрдВрдЯрдЗрд╡реЗрдВрдЯ рдХреЛ рди рдХреЗрд╡рд▓ WM_PAINT рд╕реЗ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдЕрдиреНрдп рд╕реЗрд╡рд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рднреА рдореЗрд░реЗ рд▓рд┐рдП рдЕрдЬреНрдЮрд╛рдд рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдиреАрдЪреЗ рдПрдХ рд╕рдорд╛рдзрд╛рди рджреВрдВрдЧрд╛ рдХрд┐ рдореИрдВ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рд╕реЗ рдХреИрд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рд╛ред
рддреЛ рд╕рдорд╛рдзрд╛рди рд╣реИ:
рдореИрдВрдиреЗ рдкрд╣рд┐рдпрд╛ рдХреЛ рд╕реБрджреГрдврд╝ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдХреНрдпреВрдЯреА рдХреЗ рд╕рд╛рде рджреЗрд╢реА рд╡рд┐рдЬреЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рджреЗрд╢реА рд╡рд┐рдЬреЗрдЯ рд╣реА QWidget рдХреЗ рдЕрдВрджрд░ рд╣реЛрдЧрд╛ред рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рд╡рд┐рдВрдбреЛ рдореЗрдВ рдпреЛрдЬрдирд╛рдмрджреНрдз рд░реВрдк рд╕реЗ рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рд╡рд┐рдВрдбреЛ рд╣реИрдВрдбрд▓рд░ рдмрдирд╛рдПрдВред рд╡рд╣ рд╡рд┐рдВрдбреЛ рдХреНрд▓рд╛рд╕ рдХреЛ рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░рдиреЗ рдФрд░ рд╡рд┐рдЬреЗрдЯреНрд╕ рдХреЛ рдореИрд╕реЗрдЬ рдлреЙрд░рд╡рд░реНрдб рдХрд░рдиреЗ рдХрд╛ рдзреНрдпрд╛рди рд░рдЦреЗрдЧрд╛ред
рдЖрдкрдХреЛ рдореВрд▓ рд╡рд┐рдЬреЗрдЯ рдХреЗ рд▓рд┐рдП рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рд╕реЗ QApplication рдХреЛ рднреА рд░реЛрдХрдирд╛ рд╣реЛрдЧрд╛ред рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ libqxt рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ QxtApplication :: installNativeEventFilter рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдПрдХ рдФрд░ рд╡рд┐рдХрд▓реНрдк QCoreApplication :: winEventFilter рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рд╣реИред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ HWND рдХреЛ рдореИрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП WindowProcMapper рдХреНрд▓рд╛рд╕ рд▓рд┐рдЦрд╛ред
nativewidgetimpl.h
namespace Native { class NativeWndFilter : public QxtNativeEventFilter { public: inline NativeWndFilter() { } inline void insert(HWND h) { m_wnds.insert(h); } inline void remove(HWND h) { m_wnds.remove(h); } inline bool contains(HWND h) { return m_wnds.contains(h); } bool winEventFilter(MSG * msg, long *result) override; private: QSet<HWND> m_wnds; }; template<typename T> class WindowProcMapper { public: WindowProcMapper(const wchar_t *className); ~WindowProcMapper(); inline T *getWindow(HWND hwnd) const; inline void insertWindow(HWND hwnd, T *ptr); inline void removeWindow(HWND hwnd); ATOM getRegisterResult(); bool registerWindowClass(); inline static WindowProcMapper<T> *instance() { return self; } private: QHash<HWND, T*> m_hash; LPCWSTR m_className; ATOM m_registerResult; static WindowProcMapper *self; static LRESULT CALLBACK WindowProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam); NativeWndFilter *m_filter; }; }
рджреЗрд╢реА рд╡рд┐рдЬреЗрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдг рдмрдирд╛рдПрдБ:
nativewidget.h
namespace Native { struct NativeWidgetPrivate; class NativeWidget : public QWidget { Q_OBJECT public: NativeWidget(QWidget *parent = nullptr); NativeWidget(const QString &wndName, QWidget *parent = nullptr); ~NativeWidget(); WId nativeHWND() const; HDC getNativeDC() const; void releaseNativeDC(HDC hdc) const; QString wndName() const; protected: NativeWidget(NativeWidgetPrivate *p, const QString &wndName, QWidget *parent = nullptr); void paintEvent(QPaintEvent *ev) override; void resizeEvent(QResizeEvent *ev) override; virtual bool nativeWinEvent(MSG *msg, long *result); QScopedPointer<NativeWidgetPrivate> d_ptr; private: void init(); Q_DECLARE_PRIVATE(NativeWidget); }; void NativeWidget::paintEvent(QPaintEvent *ev) { Q_D(NativeWidget); SendMessage(d->m_hwnd, WM_PAINT, 0, 0); ev->accept(); } void NativeWidget::resizeEvent(QResizeEvent *ev) { Q_D(NativeWidget); const QSize &sz = ev->size(); SetWindowPos(d->m_hwnd, NULL, 0, 0, sz.width(), sz.height(), 0); QWidget::resizeEvent(ev); } }
рджреЗрд╢реА рд╡рд┐рдЬреЗрдЯ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЖрдХрд╛рд░ рдФрд░ рдкреЗрдВрдЯ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЬрдм QWidget рдмрджрд▓рддрд╛ рд╣реИ рддреЛ рд╡реЗ рдореВрд▓ рд╡рд┐рдЬреЗрдЯ рдореЗрдВ рдИрд╡реЗрдВрдЯ рднреЗрдЬреЗрдВрдЧреЗред
рдирд┐рдЬреА рд╡рд░реНрдЧ рджреЗрд╢реА рд╡рд┐рдЬреЗрдЯ рдХреЗ рдкреНрд░рдмрдВрдзрди рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рд▓реЗрдЧрд╛ред рдпрд╣ windowsEvent рдореЗрдердб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ NativeWidget :: nativeWinEvent рдореЗрдВ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
namespace Native { struct NativeWidgetPrivate { NativeWidgetPrivate(NativeWidget *q); ~NativeWidgetPrivate(); inline HWND winID() const; HDC getDC() const; void releaseDC(HDC hdc) const; QRect windowPlacement() const; virtual bool createWindow(QWidget *parent); void sendEvent(QEvent *ev); inline bool isCreating() const { return m_creating; } LRESULT windowsEvent(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam); HWND m_hwnd; mutable HDC m_hdc; bool m_creating; void sendToWidget(uint msg, WPARAM wparam, LPARAM lparam); QString m_wndName; NativeWidget *const q_ptr; Q_DECLARE_PUBLIC(NativeWidget); }; }
рд╡реАрдбрд┐рдпреЛ рд╡рд┐рдЬреЗрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, WM_PAINT рдФрд░ WM_ERASEBACKGROUND рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
bool MovieScreen::nativeWinEvent(MSG *msg, long *result) { Q_D(MovieScreen);
рдирдореВрдирд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
IVMRWindowlessControl9 *m_pVideoRenderer9; MovieScreenPrivate:: updateMovie() { If (isPaused()) { HDC hdc = getHDC(); m_pVideoRenderer9->Repaint_Video(winID(), hdc); releaseHDC(hdc); } } MovieScreenPrivate::resizeVideo() { long lWidth, lHeight; HRESULT hr = m_pVideoRenderer9->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL); if (SUCCEEDED(hr)) { RECT rcSrc, rcDest;
рдареАрдХ рд╣реИ, рдЕрдВрдд рдореЗрдВ рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:
рд╕реВрддреНрд░реЛрдВ рдХреЛ
рдпрд╣рд╛рдВ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИред