[Qt] is it possible to call private grabMouseWhileInWindow function?

Den Jean Den.Jean at telenet.be
Sun Jan 4 14:50:34 CET 2009


On Thursday 01 January 2009 16:43:21 Paul Ishenin wrote:
> Qt mouse grab is very heavy. On windows it can grab input so that only
> ctrl+alt+del can unlock this grab. Qt installs windows hook which is imo
> a very big hack. LCL uses mouse grabs often and we dont need so heavy
> grabs since LCL can lock the whole system with them. At the same moment
> qt guys uses grabMouseWhileInWindow for their tasks. Can we publish this
> function in the bindings library then I will use it for windows-qt
> application.

grabMouseWhileInWindow is not only private, but also the implementation
of grabMouseWhileInWindow writes in local private variables, that are used
by grab/release mouse to check for existing grabs.
If we would just write a grabMouseWhileInWindow (i.e. grab w/o hook), we
cannot correctly update those local private variables. Other calls to 
grab/release would not work correctly.

The capture is windows call SetCapture, 
the hook is windows call SetWindowsHookExA
the local variables are mouseGrb,mouseGrbCur,journalRec
code from Qt:
./gui/kernel/qwidget_win.cpp

... local variables in qwidget_win.cpp

static QWidget *mouseGrb    = 0;
static QCursor *mouseGrbCur = 0;
static QWidget *keyboardGrb = 0;
static HHOOK   journalRec  = 0;

...
void QWidgetPrivate::grabMouseWhileInWindow()
{
    Q_Q(QWidget);
    if (!qt_nograb()) {
        if (mouseGrb)
            mouseGrb->releaseMouse();
        Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
        SetCapture(q->effectiveWinId());
        mouseGrb = q;
#ifndef QT_NO_CURSOR
        mouseGrbCur = new QCursor(mouseGrb->cursor());
#endif
    }
}
...
#ifndef Q_OS_WINCE
void QWidget::grabMouse()
{
    if (!qt_nograb()) {
        if (mouseGrb)
            mouseGrb->releaseMouse();
        journalRec = SetWindowsHookExA(WH_JOURNALRECORD,
(HOOKPROC)qJournalRecordProc, GetModuleHandleA(0), 0);
        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
        SetCapture(effectiveWinId());
        mouseGrb = this;
        mouseGrbCur = new QCursor(mouseGrb->cursor());
    }
}
void QWidget::releaseMouse()
{
    if (!qt_nograb() && mouseGrb == this) {
        ReleaseCapture();
        if (journalRec) {
            UnhookWindowsHookEx(journalRec);
            journalRec = 0;
        }
        if (mouseGrbCur) {
            delete mouseGrbCur;
            mouseGrbCur = 0;
        }
        mouseGrb = 0;
    }
}
#endif
....





More information about the Qt mailing list