determine if the mouse is pressed in a given moment

I’m wondering if the Figure class has some (probably hidden) property that expresses if the mouse is pressed (and which button) in the moment that the moment that the property is read. If the figure had an event for button up and down events that would also solve my problem.
I know I could set WindowButtonDownFcn and WindowButtonUpFcn to inform a global variable to keep track on when the mouse is used, but that's deeply unpractical (in my code WindowButtonDownFcn gets changed frequently depending on the actions of the user)

 Accepted Answer

Jan
Jan on 19 Sep 2017
Edited: Jan on 19 Sep 2017
It would be easy, if you do not change the WindowButtonDownFcn frequently, but keep it statically and use a persistent variable for branching. Then you had to insert the code to store the button state at one location only.
If you check the button state, you have to consider the currently active window also. You do not want to react to clicks in the task bar or the desktop.
[EDITED] The FEX submission is not working out of the box. Try this:
% !!! UNTESTED !!!
function [L, R, M] = GetMouseKeyStatus()
if ~ispc
error('Running under Windows only.');
end
if ~libisloaded('user32')
loadlibrary('user32.dll', 'user32.h');
end
L = calllib('user32', 'GetAsyncKeyState', int32(1)) ~= 0;
R = calllib('user32', 'GetAsyncKeyState', int32(2)) ~= 0;
M = calllib('user32', 'GetAsyncKeyState', int32(4)) ~= 0;
end

20 Comments

Thanks Jan... hm, a pity this option is only available in Windows. I'll try it, anyway.
It seems LOADLIBRARY is not working on my system (Windows 10, 20H2)
K>> loadlibrary('user32.dll', 'user32.h')
Error using loadlibrary
Could not find file user32.h.
Error in loadlibrary
user32.dll still exists however.
Here is my workaround. I create an h-file called WinMouse.h and place it together with ismousedpressed.m
function keypressed = ismousedpressed()
% keypressed = ismousedpressed()
% returns
% 0 no button is pressed
% 1 is left button
% 2 is right button
% 3 is scroll button push (not scrolling)
% Restriction: Windows only
% TIP: call ismousedpressed() once when your app start
% so that when really needed; ismousedpressed() returns result faster.
%
% Author: Mbvalentin
% https://www.mathworks.com/matlabcentral/fileexchange/61976-check-if-mouse-button-is-pressed
% Modified by Bruno Luong
if ~libisloaded('user32')
try
loadlibrary('C:\WINDOWS\system32\user32.dll', 'user32.h');
catch
% user.h is removed on certain recent version of Windows
% We replace with a simple customized header file
here = fileparts(mfilename('fullpath'));
loadlibrary('C:\WINDOWS\system32\user32.dll', [here '\WinMouse.h']);
end
end
left = calllib('user32','GetAsyncKeyState',int32(1)) ~= 0;
right = calllib('user32','GetAsyncKeyState',int32(2)) ~= 0;
scroll = calllib('user32','GetAsyncKeyState',int32(4)) ~= 0;
keypressed = max([1 2 3].*double([left right scroll]));
end % ismousedpressed
File WinMouse.h, this suppose the GetAsyncKeyState signature won't change on Windows OS (which likely the case)
/* WinMouse.h
* Replacement of user32.h if it's not available
see ismousedpressed.m
This file must be located at the same place as ismousedpressed */
short GetAsyncKeyState(
int vKey
);
Dear Bruno
I am interested in this code but I don't know how to have it function.
Thanks
@Matteo Verardo do you have a specific question ?
In the callback of "WindowButtonMotionFcn" I need to know which mouse buttons are pressed during the movement of the mouse
I could have these cases:
1) central button (wheel) is pressed
2) keeping the wheel pressed, the right button is just clicked and released.
3) wheel and right buttons are pressed in the same time
The code that I have found here does not work or I am not able to use it.
You missunderstand the code ismousedpressed(), it cannot do what you ask for, return multiple buttons state, click/release event.
You have the source code you might try to modify it to suit to your need.
Hi, with current version Matlab 2023b I got this result :
>> loadlibrary('user32.dll', 'user32.h')
Warning: Warnings messages were produced while parsing. Check the functions you intend to use for correctness. Warning text can be viewed using:
[notfound,warnings]=loadlibrary(...)
> In loadlibrary
Error loading library intermediate output follows.
The actual error is at the end of this output.
*********
The system cannot find the file specified.
'perl' is not recognized as an internal or external command,
operable program or batch file.
*********
Error using loadlibrary
The MATLAB program file describing your library could not be found, possible Perl or file system error.
How to fix that ?
Thanks
@Matthieu I just check, the fix I posted in 14 Nov 2020 still work forMATLAB R2022B and on Windows 11 23H2.
@Bruno Luong Ok Bruno I havn't seen your tip with the ''dummy'' WinMouse.h containing
short GetAsyncKeyState(int vKey);
The result is unfortunately the same ... :
Error using loadlibrary
The MATLAB program file describing your library could not be found, possible Perl or file system error.
Error in ismousedpressed (line 22)
loadlibrary('C:\WINDOWS\system32\user32.dll', [here '\WinMouse.h']);
On Windows 10 10.0.19045 + Matlab 2023b.
@Jan or @Walter Roberson is it still working with matlab 2023b the loading of user32.dll :
loadlibrary('user32.dll', 'user32.h');
or with the tip of Bruno ?
Thx
@Matthieu What this command returns?
exist('C:\WINDOWS\system32\user32.dll','file')
Hi Bruno,
ans = 2
and the file WinMouse.h is placed at same location as ismousedpressed.m.
@Matthieu strange. I test on a second PC (R2023b & Window 11) and it still works on my side.
If I delete WinMouse.h then the error I get is:
>> ismousedpressed
Error using loadlibrary
Could not find file C:\Users\bruno\BLUDocuments\Robot\RobotSkinCalibration\SCT_Skin_Calibration_Tool\MiscTools\WinMouse.h.
Error in loadlibrary
Error in ismousedpressed (line 26)
loadlibrary('C:\WINDOWS\system32\user32.dll', [here '\WinMouse.h'], 'mfilename', 'WinMouse');
After I restore it loadlibrary workwell that those files are created by MATLAB
  • user32_thunk_pcwin64.dll
  • user32_thunk_pcwin64.exp
  • user32_thunk_pcwin64.lib
  • user32_thunk_pcwin64.obj
It looks like the perl.m is not found on your installation
can you do this under MATLAB and report the result
% should return C:\Program Files\MATLAB\R2023b\toolbox\matlab\general\perl.m
which perl.m
Hi Bruno, the perl.m file is well found (like you). My win version is W10 10.0.19045 if can make some difference ?!
I don't know. Are you able to do loadlibrary at all (not specifically he user32.dll)?
Hi, if I try with the example given in the help of LoadLibrary :
cd('C:\Program Files\MATLAB\R2023b\extern\examples\shrlib')
loadlibrary('shrlibsample')
The rror is the same :
Warning: Warnings messages were produced while parsing. Check the functions you intend to use for correctness. Warning text can be viewed using:
[notfound,warnings]=loadlibrary(...)
> In loadlibrary
Error loading library intermediate output follows.
The actual error is at the end of this output.
*********
The system cannot find the file specified.
'perl' is not recognized as an internal or external command,
operable program or batch file.
*********
Error using loadlibrary
The MATLAB program file describing your library could not be found, possible Perl or file system error.
If I break at line 86 in perl.m I can see :
Line 86 :
[status, result] = system(cmdString);
cmdString =
'set PATH=C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\;%PATH%&perl "C:\Program Files\MATLAB\R2023b\toolbox\matlab\general\private\prototypes.pl" shrlibsample.i -outfile=shrlibsample_proto.m -thunkfile=shrlibsample_thunk_pcwin64.c -header=shrlibsample.h'
and when I launch :
K>> [status, result] = system(cmdString)
status =
1
result =
'The system cannot find the file specified.
'perl' is not recognized as an internal or external command,
operable program or batch file.
'
In parralel I added in the path of variable environnement : the path (C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\) to perl.exe BUT the result is the same.
It is like it doesn't find perl.exe or doesn't understand this DOS command...
My perl path does not contain toolbox
K>> perlInst = fullfile(matlabroot, 'sys\perl\win32\bin\')
perlInst =
'C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\'
K>> cmdString = ['set PATH=',perlInst, ';%PATH%&' cmdString]
cmdString =
'set PATH=C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\;%PATH%&set PATH=C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\;%PATH%&set PATH=C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\;%PATH%&perl "C:\Program Files\MATLAB\R2023b\toolbox\matlab\general\private\prototypes.pl" WinMouse.i -outfile=WinMouse.m -thunkfile=user32_thunk_pcwin64.c -header=WinMouse.h'
There seems to be something that is not standard in your MATLAB installation.
Hi,
my variable 'perlInst' contains exactly the same as you.
Your cmdString is similar, containing also :
%PATH%&perl "C:\Program Files\MATLAB\R2023b\toolbox\matlab\general\private\prototypes.pl"
and this is identical also : &set PATH=C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\;
Finally a REBOOT (!) of my computer finally solved the problem, incredible !! ?? ...
BUT : I then removed the environnement variable PATH to 'C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\' and reboot Matlab and ismousedpressed.m is NOT working anymore...
So I recreated this PATH entry in the environnement variable : C:\Program Files\MATLAB\R2023b\sys\perl\win32\bin\, reboot MATLAB again and ismousedpressed.m is working again !!
So it seems that perl.exe was not reachable by Matlab as DOS command and it seems that PATH of environnement variables are loaded at Matlab startup (?).
Thanks for your help Bruno !
For sure the PATH is loaded at the MATLAB startup (or in general any windows program). What I don't understand is that the system commannd in perl.m use the full absolute path, and why it needs the path environment?
Anyway glad you solve the issue.

Sign in to comment.

More Answers (1)

Ankit Bhardwaj
Ankit Bhardwaj on 24 Apr 2017
Edited: Ankit Bhardwaj on 24 Apr 2017
You can use ButtonDownFcn callback for your figure. This callback executes whenever the user clicks a mouse button while the pointer is in the figure window, but not over a child object such as a uicontrol, uipanel, axes, or axes child. Moreover, mouse selection type returns 'normal', 'extend' , 'alt' , or 'open'. MATLAB maintains this property to provide information about the last mouse-button press that occurred within the figure window. This information indicates the type of selection made. Please go through the following documentation to learn about callback properties of figure object.
https://www.mathworks.com/help/matlab/ref/figure-properties.html#zmw57dd0e274973

2 Comments

Hi Ankit,
thanks for your suggestion. This would be rather unpractical in my case, as in my GUI I define a large number of "modus" (similar to the zoom, rotation, etc of a regular matlab figure). This means, a lot of ButtonDownFcns that change during runtime. To implement your solution, I would be forced to make certain that every ButtonDownFcn triggers an event that tells some listener that the button was pressed, and that every ButtonUpFcn broadcasts the release of the button. That'd be a titanic effort, specially because I rely on a large library of code that I didn't develop specifically for this application (and which I don't wish to modify, as they are used by other applications).
cheers, Daniel

Sign in to comment.

Asked:

on 21 Apr 2017

Commented:

on 12 Dec 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!