C++ – QWinWidget Inside MFC Dialog Not Repainting or Responding to Tab/Arrow keys

cmfcqtqt-mfc-migration

I am using a QWinWidget inside of an MFC dialog and the QWinWidget is not drawing itself correctly and it is not handling keyboard input correctly.

Repainting [Unsolved]

Within the QWinWidget, I have a QTableWidget. When I scroll the QTableWidget, it does not redraw itself until I stop scrolling, at which point it redraws everything. Similarly, I can type into cells in the QTableWidget and the control is not updated until I force it to re-update by scrolling up or down (it re-updates when the scrolling stops).

Since this QWinWidget is housed in an MFC CDialog, I tried overriding the CDialog's OnPaint method and only call the QWinWidget::repaint method, however this has the opposite problem where now only the QWinWidget is updated and the CDialog is never redrawn, resulting in artifacts. If I call QWinWidget::repaint and CDialog::OnPaint, the result is the same as not overriding the OnPaint method. Has anyone ever seen this problem or know how to resolve it?

Keyboard Input [Solved]

None of the controls within the QWinWidget respond to the tab key or arrow keys correctly. The tab/arrow keys simply skip over the entire QWinWidget (and all child controls). Even if I click inside the QWinWidget and select a control, the next time I press the tab key, it skips the focus completely out of the entire QWinWidget.

I noticed that the QWinWidget has two functions, QWinWidget::focusNextPrevChild and QWinWidget::focusInEvent and both of them have a comment header saying "\reimp". Am I supposed to override these functions in order to get correct tab functionality? If so, how can these functions be implemented for correct tab functionality.

Best Answer

I have fixed the keyboard input issue. The QWinWidget class needed some changes:

in the QWinWidget::init method, the WS_TABSTOP must be added to the window style:

SetWindowLong(winId(), GWL_STYLE, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP);

Also, the QWinWidget::winEvent method needs to respond to the WM_GETDLGCODE to let Windows know that it is interested in receiving key/tab inputs. I had to add this if block:

if(msg->message == WM_GETDLGCODE)
{
   *result = DLGC_WANTARROWS | DLGC_WANTTAB;
   return(true);
}

I am still working on getting the widget to paint properly.

Related Topic