27#include <QAbstractScrollArea>
28#include <QAbstractSlider>
29#include <QCoreApplication>
38#include <unordered_map>
40#ifdef KDWINUTILS_WITHMFC
67 Type = QEvent::User + 45687,
102 Q_DECLARE_FLAGS(Flags,
Flag)
111 virtual
bool Create(const
KString &lpszWindowName, Flags dwStyle, const
KRect &rect, QWidget *pParentWnd);
115 bool PostMessage(
unsigned int id, uint64_t wParam = 0, int64_t lParam = 0);
118 int64_t
SendMessage(
unsigned int id, uint64_t wParam = 0, int64_t lParam = 0);
124 template <typename U>
128 template <typename U = T>
132 template <typename U = T>
162 unsigned int nPage = -1;
176 bool SetScrollInfo(Qt::Orientation nBar, ScrollInfo *lpScrollInfo,
bool bRedraw =
true);
181 void SetScrollRange(Qt::Orientation nBar,
int nMinPos,
int nMaxPos,
bool bRedraw =
true);
191 template <
typename Class>
192 void connectMessage(
int id, Class *
object, int64_t (Class::*method)(uint64_t, int64_t));
196 template <
typename Class>
205 template <
typename Signal,
typename Class>
206 void connectRange(
const typename QtPrivate::FunctionPointer<Signal>::Object *firstWidget,
207 const typename QtPrivate::FunctionPointer<Signal>::Object *lastWidget, Signal signal,
208 Class *
object,
void (Class::*method)(
unsigned int));
243 virtual void OnHScroll(
int nSBCode,
int nPos, QAbstractSlider *pScroll) { }
245 virtual void OnVScroll(
int nSBCode,
int nPos, QAbstractSlider *pScroll) { }
266 std::optional<int64_t> handleMessageEvent(
unsigned int id, uint64_t wparam, int64_t lparam);
267 void handleFocusEvent(QObject *
id);
268 QAbstractScrollArea *scrollArea()
const;
269 QScrollBar *scrollBar(Qt::Orientation nBar)
const;
271 std::unordered_map<unsigned int, MessageHandler> m_messageHandlers;
272 std::unordered_map<QObject *, FocusHandler> m_focusHandlers;
273 int64_t m_messageResult;
302 auto paintEvent =
static_cast<QPaintEvent *
>(event);
305 if (event->type() == QEvent::FocusOut) {
306 handleFocusEvent(watched);
308 return T::eventFilter(watched, event);
314 m_flags.setFlag(flag, on);
322 if (dwStyle.testAnyFlags({Flag::HScroll, Flag::VScroll})) {
323 auto scrollArea =
new QAbstractScrollArea(
this);
325 scrollArea->setFrameShape(QFrame::NoFrame);
326 scrollArea->setLineWidth(0);
327 auto layout =
new QHBoxLayout(
this);
328 layout->addWidget(scrollArea);
329 layout->setContentsMargins({});
330 connectScroll(scrollArea->horizontalScrollBar());
331 connectScroll(scrollArea->verticalScrollBar());
332 if (!dwStyle.testAnyFlag(Flag::HScroll))
333 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
334 if (!dwStyle.testAnyFlag(Flag::VScroll))
335 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
337 scrollArea->viewport()->installEventFilter(
this);
340 T::setParent(pParentWnd);
341 T::setGeometry(rect);
350 QCoreApplication::postEvent(
this, message);
358 QCoreApplication::sendEvent(
this, &message);
359 return m_messageResult;
372 return dynamic_cast<U
>(T::parent());
379 return qobject_cast<KWidget *>(T::parent());
385 if (m_flags.testAnyFlags({Flag::HScroll, Flag::VScroll})) {
386 const auto &viewportRect = scrollArea()->viewport()->rect();
387 *rect = viewportRect;
389 rect->
SetRect(0, 0, T::width(), T::height());
396 const auto &geom = T::frameGeometry();
397 rect->
SetRect(T::x(), T::y(), geom.width(), geom.height());
403 auto sb = scrollBar(nBar);
404 if (nMask.testFlag(ScrollMask::Range)) {
405 lpScrollInfo->
nMin = sb->minimum();
406 lpScrollInfo->
nMax = sb->maximum();
408 if (nMask.testFlag(ScrollMask::Page))
409 lpScrollInfo->
nPage = sb->pageStep();
410 if (nMask.testFlag(ScrollMask::Pos))
411 lpScrollInfo->
nPos = sb->value();
412 if (nMask.testFlag(ScrollMask::TrackPos))
413 lpScrollInfo->
nTrackPos = sb->sliderPosition();
414 lpScrollInfo->
fMask = nMask;
421 return scrollBar(nBar)->maximum();
427 return scrollBar(nBar)->value();
433 *lpMinPos = scrollBar(nBar)->minimum();
434 *lpMaxPos = scrollBar(nBar)->maximum();
440 auto sb = scrollBar(nBar);
441 if (lpScrollInfo->
fMask.testFlag(ScrollMask::Range))
442 sb->setRange(lpScrollInfo->
nMin, lpScrollInfo->
nMax);
443 if (lpScrollInfo->
fMask.testFlag(ScrollMask::Page))
444 sb->setPageStep(lpScrollInfo->
nPage);
445 if (lpScrollInfo->
fMask.testFlag(ScrollMask::TrackPos) && lpScrollInfo->
nTrackPos != -1)
446 sb->setSliderPosition(lpScrollInfo->
nTrackPos);
447 if (lpScrollInfo->
fMask.testFlag(ScrollMask::Pos))
448 sb->setValue(lpScrollInfo->
nPos);
449 if (lpScrollInfo->
fMask.testFlag(ScrollMask::DisableNoScroll)) {
452 scrollArea()->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
454 scrollArea()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
463 const int oldValue = scrollBar(nBar)->value();
464 scrollBar(nBar)->setValue(nPos);
471 scrollBar(nBar)->setRange(nMinPos, nMaxPos);
477 m_messageHandlers[id] = method;
483 auto it = m_focusHandlers.find(
id);
484 if (it != m_focusHandlers.end()) {
490template <
typename Class>
493 connectMessage(
id, [
object, method](uint64_t wParam, int64_t lParam) {
494 return (object->*method)(wParam, lParam);
501 m_focusHandlers[w] = method;
502 w->installEventFilter(
this);
506template <
typename Class>
509 connectKillFocus(w, [
object, method]() {
510 return (object->*method)();
517 auto callback = [abstractSlider,
this](
int action) {
518 if (abstractSlider->orientation() == Qt::Horizontal)
519 OnHScroll(action, abstractSlider->sliderPosition(), abstractSlider);
521 OnVScroll(action, abstractSlider->sliderPosition(), abstractSlider);
523 T::connect(abstractSlider, &QAbstractSlider::actionTriggered,
this, callback);
527template <
typename Signal,
typename Class>
529 const typename QtPrivate::FunctionPointer<Signal>::Object *lastWidget,
530 Signal signal, Class *
object,
void (Class::*method)(
unsigned int))
532 const int firstId = firstWidget->property(mfcIDProperty).toInt();
533 const int lastId = lastWidget->property(mfcIDProperty).toInt();
534 if (firstId == 0 || lastId == 0)
536 auto widgets = T::template findChildren<QWidget *>();
537 for (
auto widget : widgets) {
538 const int id = widget->property(mfcIDProperty).toInt();
539 if (
id >= firstId &&
id <= lastId) {
540 T::connect(
dynamic_cast<typename QtPrivate::FunctionPointer<Signal>::Object *
>(widget), signal,
object,
541 [
object, method,
id] {
542 (
object->*method)(
id);
551 T::paintEvent(event);
557 switch (event->button()) {
559 OnLButtonDown(event);
561 case Qt::MiddleButton:
562 OnMButtonDown(event);
564 case Qt::RightButton:
565 OnRButtonDown(event);
570 T::mousePressEvent(event);
576 switch (event->button()) {
580 case Qt::MiddleButton:
583 case Qt::RightButton:
589 T::mouseReleaseEvent(event);
595 switch (event->button()) {
597 OnLButtonDblClk(event);
599 case Qt::MiddleButton:
600 OnMButtonDblClk(event);
602 case Qt::RightButton:
603 OnRButtonDblClk(event);
608 T::mouseDoubleClickEvent(event);
615 T::mouseMoveEvent(event);
623 if (m_flags.testAnyFlags({Flag::HScroll, Flag::VScroll}))
631 if (event->key() == Qt::Key_F1 && event->modifiers() == Qt::NoModifier && m_flags.testFlag(Flag::HelpInfo)) {
636 T::keyPressEvent(event);
643 T::keyReleaseEvent(event);
649 T::resizeEvent(event);
658 auto result = handleMessageEvent(message->id, message->wparam, message->lparam);
659 m_messageResult = result.value_or(0);
660 return result.has_value();
668 auto it = m_messageHandlers.find(
id);
669 if (it == m_messageHandlers.end())
671 return it->second(wparam, lparam);
685 return scrollArea()->horizontalScrollBar();
687 return scrollArea()->verticalScrollBar();
The KDialog class is used to replace MFC KDialog.
Definition kdialog.h:40
Event use internally to map the MFC message handling.
Definition kwidget.h:56
uint64_t wparam
Definition kwidget.h:71
KMessageEvent(unsigned int messageId, uint64_t w, int64_t l)
Definition kwidget.h:58
unsigned int id
Definition kwidget.h:70
@ Type
Definition kwidget.h:67
int64_t lparam
Definition kwidget.h:72
The KPainter class is used to paint on a widget.
Definition kpainter.h:51
The KRect class defines a rectangle in the plane using integer precision.
Definition krect.h:40
void SetRect(int left, int top, int right, int bottom)
Sets the dimensions of KRect.
The KString class provides a Unicode character string.
Definition kstring.h:45
#define KDWINUTILS_EXPORT
Definition kdwinutils_export.h:31
#define KDWINUTILS_BEGIN_NAMESPACE
Definition kdwinutils_global.h:27
#define KDWINUTILS_END_NAMESPACE
Definition kdwinutils_global.h:28