Build & register MyActiveXControl. I have also attached myactivexcontrol_ocx which you can directly register & use.
Place any text file named ReadMe.txt in C:\Temp folder. Of course you can change the location from the ActiveX code.
Here are the contents of the HTML file:
<HEAD>
<TITLE>Drag & Drop Test</TITLE>
<BODY>
<CENTER>
This is the key to the example. The OBJECT
tag is a new tag used to download ActiveX
components. Once the ActiveX component is available,
you can set its properties by using the PARAM tag.
–>
CLASSID=”clsid:90EDC5CE-75EE-47F2-AB0E-7E7444FD9257″
ID=”MYACTIVEXCONTROL.MyActiveXControlCtrl.1″
</OBJECT>
</BODY>
</HTML>
In fast dragging (even if left mouse button is down) we see only this log:
[3508] grfKeyState is: 0
[3508] DRAGDROP_S_DROP <= The files drops to the same IE window.
grfKeyState never changed to 1 – which is the issue. This however does not happen on Windows 7 OS (32 bit & 64 bit both).
Yes. This is how I fixed it and has worked from Windows 7 to Windows 10.
File Name: DropSource.h
Function Name: HRESULT CDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
============
Instead of relying on grfKeyState, I checked the mouse button state using GetKeyState() API and return DRAGDROP_S_DROP when the mouse button is released. I have tested it and it works fine.// Modified QueryContinueDrag() codeHRESULT CDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
{
DWORD my_grfKeyState = 0;
// If the high-order bit is 1, the key is down; otherwise, it is up.
if((GetKeyState(VK_LBUTTON) & 0x80) != 0)
{
my_grfKeyState = 1;
}
TCHAR buffer[100];
swprintf_s(buffer, 100, L”grfKeyState is: %d”, grfKeyState);
::OutputDebugString(buffer);
swprintf_s(buffer, 100, L”my_grfKeyState is: %d”, my_grfKeyState);
::OutputDebugString(buffer);
if (fEscapePressed)
{
::OutputDebugString(L”DRAGDROP_S_CANCEL”);
return DRAGDROP_S_CANCEL;
}
if (!(my_grfKeyState & (MK_LBUTTON | MK_RBUTTON)))
{
::OutputDebugString(L”DRAGDROP_S_DROP”);
return DRAGDROP_S_DROP;
}
::OutputDebugString(L”S_OK”);
return S_OK;
}
============
I made some changes in CDropSource::QueryContinueDrag() (see below) to test PeekMessage(). PeekMessage seems to be working fine. So the only anomaly what we see in case of the ActiveX hosted in IE11, is for the first time when grfKeyState never changes to 1 from 0.
if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST)) never becomes TRUE.
{
TCHAR buffer[100];
MSG msg;
DWORD my_grfKeyState = 0;
::OutputDebugString(buffer);
//auto HaveAnyMouseMessages = [&]() -> BOOL
//{
// return PeekMessage(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);
//};
while (!PeekMessage(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE))
{
// Note: all keyboard messages except escape are tossed. This is
// fairly reasonable since the user has to be holding the left
// mouse button down at this point. They can’t really be doing
// too much data input one handed.
if ((PeekMessage(&msg, 0, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE)
|| PeekMessage(&msg, 0, WM_SYSKEYDOWN, WM_SYSKEYDOWN, PM_REMOVE))
&& msg.wParam == VK_ESCAPE)
{
fEscapePressed = TRUE;
break;
}
}
{
if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
{
my_grfKeyState = GetControlKeysStateOfParam(msg.wParam);
swprintf_s(buffer, 100, L”my_grfKeyState after PeekMessage is: %d”, my_grfKeyState);
::OutputDebugString(buffer);
}
}
if((GetKeyState(VK_LBUTTON) & 0x80) != 0)
{
my_grfKeyState1 = 1;
}
//// DWORD my_grfKeyState = GetAsyncKeyState(VK_LBUTTON); //GetKeyState(VK_LBUTTON);
::OutputDebugString(buffer);
//swprintf_s(buffer, 100, L”my_grfKeyState is: %d”, my_grfKeyState);
//::OutputDebugString(buffer);if (fEscapePressed)
{
::OutputDebugString(L”DRAGDROP_S_CANCEL”);
return DRAGDROP_S_CANCEL;
}
// if(my_grfKeyState == 0 && grfKeyState == 0)
if (!(my_grfKeyState & (MK_LBUTTON | MK_RBUTTON)))
{
::OutputDebugString(L”DRAGDROP_S_DROP”);
return DRAGDROP_S_DROP;
}
return S_OK;
}
[8452] GetUIObjectOfFile succeeded
[8452] DoDragDrop
[8452] my_grfKeyState before PeekMessage is: 0
[8452] my_grfKeyState after PeekMessage is: 1
[8452] my_grfKeyState1 from GetKeyState() is: 1
[8452] S_OK
[8452] my_grfKeyState before PeekMessage is: 0
[8452] my_grfKeyState1 from GetKeyState() is: 1
[8452] DRAGDROP_S_DROP
=========
Operating System: Windows 8.1 x64 (Version 6.3, Build: 9600)
ole32.dll version: 6.3.9600.18256
Installed this KB. Restarted the machine.
ole32.dll version: 6.3.9600.18403