Windows 10 : Pen (stylus) not working on MFC application - c++

I have an MFC application that works fine with Pen (Stylus) under Windows 7, but unfortunately, it does not work on Windows 10.
Under Windows 7, I am able to scroll vertically with the stylus WITHOUT using (clicking and dragging) the scroll bar, i can scroll vertically by clicking and dragging from anywhere in my dialog (formview)
Under Windows 10, I am not able to scroll vertically with the stylus WITHOUT using (clicking and dragging) the scroll bar. I must click (and drag) with the Stylus on the scroll bar to scroll vertically
My need :
I need to be able to scroll vertically with the stylus WITHOUT using (clicking and dragging) the scroll bar on Windows 10
Detail:
I am on Windows 10 with Visual studio 2010.
My opinion
I think that the version of MFC100.dll (related to my Visual Studio 2010) does probably not support the functionality of the stylus under Windows 10 because the code works correctly under windows 7
Someone has already encountered this problem ?
Thanks.

I post this answer to help people who are in the same situation as me.
1. Introduction
Interaction with the scrollbar can be can be done using (It’s probably not the only methods that exist):
SetScrollPos coupled with ScrollWindow. The first scrolls the bare scroll, the second scrolls the contents of the window
ScrollToPosition which scrolls both the scroll bare and the contents of the window
The first method (SetScrollPos coupled with ScrollWindow) requires management of all scrollbar informations : scrollable size, current position, ... and recalculate it on each OnSize () (which is not too trivial ...)
With the seconde method (ScrollToPosition) mode, all we have to do is to call the ScrollToPosition with the desired scrolling size. We don't have to manage the details of the scroll bare, Windows does it for us!
For some reason that I don't know, the stylus scroll functionality on Windows 10 does not have the same behavior on Windows 7 : The scrollbar scrolls but not the contents of the window !!!
2. Solution
Having spent several hours on this problem, I conclude that the simple solution to work around this problem is to use the ScrollToPosition function as much as possible. And in this case, you just need to calculate scrolled size (delta) which is defined by:
Starts when the mouse button is pressed (Stulys pointed) (use ON_WM_LBUTTONDOWN)
Extended/reduced during drag (use ON_WM_MOUSEMOVE)
Ends when the button is released (use ON_WM_LBUTTONUP)
All you have to do is call the ScrollToPosition function with the calculated delta. This will allow you to move from an extremely complicated management mode to a few things that look like this:
ON_WM_LBUTTONDOWN
void CMyView::OnLButtonDown (UINT nFlags, CPoint point)
{
// Code here ...
POINT p;
GetCursorPos(&p);
ScreenToClient ( &p); // Convert to screen coordinates
m_dragPosition = p; // m_dragPosition : member variable to store click position
m_bMouseDown = true; // Set Flag to true
CWnd::OnLButtonDown (nFlags, point) ;
}
ON_WM_LBUTTONUP
void CMyView::OnLButtonUp (UINT nFlags, CPoint point)
{
// Code here ...
m_bMouseDown = false;
CWnd::OnLButtonUp(nFlags, point);
}
ON_WM_MOUSEMOVE
void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
int delta = p.y - m_dragPosition.y;
// Use absolute value to take into account top/bottom scrolling
if ( abs (delta) > SCROLLING_STEP_SIZE)
{
CPoint pp = GetScrollPosition (); // Get current scrollbar position
pp.y += -delta;
pp.x = 0; // I'm intersting only for vertical scrolling
ScrollToPosition (pp); // Scroll to new position
UpdateWindow (); // This redraw new showed area
m_dragPosition = p; // Update drag position
}
}
By adding this, you avoid explicit management which is not at all trivial...
Hope this will help those who are in the same situation as me

Related

MFC getting mouse pointer coordinate problem

I'm trying to get coordinate of the Rect (Picture control) but It's a bit glitchy.
So here're the process that I've done.
1st. made a picture control
2nd. I've earned WindowRect through GetWindowRect
// myDialogDlg.cpp
CRect m_rcDisp // (is acually in myDialogDlg.h)
BOOL myDialogDlg::OnInitDialog()
{
// IDC_PIC1 == ID of the (static) picture control
GetDlgItem(IDC_PIC1)->GetWindowRect(m_rcDisp);
...
}
3rd. I've made OnMouseMove event, and used PtInRect to make some action while mouse pointer is inside the picture control.
// myDialogDlg.cpp
void myDialogDlg::OnMouseMove(UINT nFlags, CPoint point)
{
CString debug;
{
if (m_rcDisp.PtInRect(point))
{
// my event starts
OutputDebugString(_T("here"));
if (m_CamTrig == CAMERA_TRIG_SW)
{
m_CurSor.x = point.x;
m_CurSor.y = point.y;
InvalidateRect(m_rcDisp, NULL);
}
// my event ends
}
}
CDialogEx::OnMouseMove(nFlags, point);
}
and... where actually PtInRect works is about here inside the red box
:( Hope I get the best answer.
thx!
GetWindowRect returns the window dimensions in screen coordinates. WM_MOUSEMOVE reports the mouse position in client coordinates. ScreenToClient1 can be used to translate from screen coordinates to client coordinates, making the picture control's window rectangle coordinates and hit testing function agree on a common origin.
This needs to be done whenever the picture control is moved relative to its parent dialog. If the picture control is never moved you only need to adjust the rectangle once.
This answer links to the Windows API documentation, since it's generally more informative and better maintained than the respective MFC entries. You can call either one from MFC code, though it's usually more convenient to just call into the CWnd members.
1 Use MapWindowPoints instead if you plan on supporting RTL and LTR layouts. See Window Layout and Mirroring for guidance.

How to set minimum size for m_wndClientArea in CMDIFramewndEx?

This is visualstudio screen.
When resizing visualstudio screen to minimum, the tabbeddocument view, left and right dialogpane are displayed with some minimum size.
After resizing IF I resize the screen to maximum by dragging it becomes like this.
Whereas in my application which is a MDI tabbed group application created using MFC feature pack.
When resizng to minimum the tabbed docuemnt and rightside pane is resized tozero width.For right pane I set the minimum size as 100 using SetMinSize().
After resizing IF I resize the screen to maximum by dragging it , the right pane is not getting displayed.
I guess, to achieve this we need to set minimum size for CMDIFramewndEx's m_wndClientArea or CDockingManager's m_rectClientAreaBounds.
How to achieve this?
If you have any other solution please suggest me.
Thanks
In order to constraint the minimum size for an window, you have to handle WM_GETMINMAXINFO message:
in header:
afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
and in cpp:
ON_WM_GETMINMAXINFO()
void CChildFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
// TODO: Add your message handler code here and/or call default
lpMMI->ptMinTrackSize.x = 100;
lpMMI->ptMinTrackSize.y = 200;
CMDIChildWnd::OnGetMinMaxInfo(lpMMI);
}

MFC PreCreateWindow to create a window that fill the screen except for the taskbar

I would like to create a window that fills the entire space of the desktop without including the Windows start menu, and without maximizing the window.
I think the code should be something like this :
BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs)
{
cs.cx = ::GetSystemMetrics(SM_CXSCREEN);
cs.cy = ::GetSystemMetrics(SM_CYSCREEN); // minus start menu height please
return CMDIFrameWnd::PreCreateWindow(cs);
}
But how do I get the height of the start menu ? Thanks.
To avoid the taskbar and any appbars, you want to fill the work area. Use the GetMonitorInfo function and look at the rcWork member. (Note that each monitor has a different work area, so you need to know which monitor you care about.)

CreateSimpleReBar in WTL vista/7 native look and feel

When using the CreateSimpleReBar in WTL the main menu bar has this blue color on mouse hover and not the native vista/7 round and transparent shape. Also for some reason the menu bar seems taller then the usual native one.
Does CreateSimpleReBar draw the menu itself or am I missing something?
http://imageshack.us/photo/my-images/259/wtlmainmenu.png/
HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
// attach menu
m_CmdBar.AttachMenu(GetMenu());
// load command bar images
m_CmdBar.LoadImages(IDR_MAINFRAME);
// remove old menu
SetMenu(NULL);
// Set m_hWndToolBar member
CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
// Add a band to the rebar represented by m_hWndToolBar
AddSimpleReBarBand(hWndCmdBar);
CreateSimpleReBar creates a rebar control, and the menu is one of the rebar bands, created by m_CmdBar.Create - WTL's CCommandBarCtrl class. The latter custom-draws the menu to mimic OS behavior, including blue highlighting with COLOR_MENUHILIGHT (atlctrlw.h).

Automatically display vertical scrollbar in multiline text edit control

On a windows mobile device I have a mutliline text edit control that is set to read-only and has some static text displayed during it's display lifetime. I would like to only display a vertical scrollbar when it's actually useful (i.e. the text is larger than the display).
I can't easily figure out if the text is to large to display because of two reasons.
There is no horizontal scroll bar displayed so the text wraps.
Under windows mobile, the win32 routines to calculate the size of what text will display does not work correctly. They return a incorrect rectangle.
The edit control must tell the scroll bar what it's scroll range is at some point. I was wondering if I could get in between then and hide the scroll bar if it's not going to be used.
This is how I solved this problem.
First off:
It only works with read-only mode of a edit control (as you don't want the text to change often).
I think is specific to Windows Mobile MFC, big windows can handle this a lot better.
The solution is very very hacky.
Solution:
I have a standard CEdit bound to the control.
CEdit m_Message;
DDX_Control(pDX, IDC_MESSAGE,
m_Message);
During the InitDialog and OnSize calls, turn on the display of the scroll bar and setup a timer message.
m_Message.ShowScrollBar(SB_VERT,
TRUE);
SetTimer(DO_ADJUST_DISPLAY_STATE, 50,
0);
In the timer handling code, use the scroll information to determine if the scroll bar needs to be displayed.
If not being displayed, turn off the scroll bar and force the window to redisplay.
void CMessageDlg::OnTimer( UINT_PTR nIDEvent )
{
switch(nIDEvent)
{
case DO_ADJUST_DISPLAY_STATE:
KillTimer(nIDEvent);
// deselect all text
m_Message.SetSel(0, 0);
SCROLLINFO info;
m_Message.GetScrollInfo(SB_VERT, &info);
if(info.nPage > (UINT)info.nMax)
{
// need to re-display the non scroll bar version
m_Message.ShowScrollBar(SB_VERT, FALSE);
// I could not find any other way to force a redisplay
// correctly without display problems...
// first move the window to a know invisible area
// then wait (using a timer) for the window to move
// then move the window back to it's original position
RECT rt;
rt.left = 0;
rt.right = 5;
rt.top = 0;
rt.bottom = 5;
m_Message.MoveWindow(&rt);
SetTimer(DO_REDISPLAY_MESSAGE, 50, 0);
}
break;
case DO_REDISPLAY_MESSAGE:
KillTimer(nIDEvent);
// m_MessagePosition holds the original position
// worked out dynamically during the WM_SIZE
// processing
m_Message.MoveWindow(&m_MessagePosition);
break;
}
}
I hope that helps out other people who may have similar requirements.
I was wondering if I could get in between then and hide the scroll bar if it's not going to be used.
I highly doubt it. But I bet you could call SetScrollInfo some time after the text box is created, and send your own scroll parameters.
EDIT: Wrong link, my bad. Here's the one for the Windows CE