小编RbM*_*bMm的帖子

从32位拖放到64位

我正在编写一个接受文件拖放的C程序.当它以32位编译时,无论如何都适用.但是当它以64位编译时,它仅适用于从64位应用程序拖动的文件:

  • 32位 - > 32位:成功
  • 64位 - > 64位:成功
  • 64位 - > 32位:成功
  • 32位 - > 64位:失败

我仍然得到WM_DROPFILES消息,但DragQueryFile没有返回任何内容(文件数为0).

这似乎是许多应用程序的问题,但我想知道是否有解决方法.

编辑:

  • 如果我将文件从64位可执行文件拖放到我的64位应用程序,wParam有一个值,如0x000000F211C000B8(表明没有强制转换问题).
  • 接下来,在不关闭我的应用程序的情况下,如果我从32位可执行文件中拖动文件,wParam将具有类似0x0000000011C000B8或0xFFFFFFFF11C000B8的内容,这意味着高位32位无效.
  • 如果我用前一条消息中的有效高位替换无效高位(在本例中,这将是0x000000F2),那么DragQueryFile可以工作!

所以数据在这里,某处,我只是不知道如何检索它们(至少没有丑陋的黑客).

编辑2:

我将不提供任何代码,因为我认为那些回答的人知道这个影响大量软件的问题.

------编辑----------

重现它的最小代码

LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    WCHAR sz[32];
    switch (uMsg)
    {
    case WM_DROPFILES:
        swprintf(sz, L"%p", wParam);// look for wParam
        MessageBox(0,0,sz,0);
        break;
    case WM_NCCREATE:
        DragAcceptFiles(hwnd, TRUE);
        break;
    case WM_NCDESTROY:
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

void minimal()
{
    static WNDCLASS wndcls = { 0, WindowProc, 0, …
Run Code Online (Sandbox Code Playgroud)

c winapi drag-and-drop

6
推荐指数
1
解决办法
1241
查看次数

谁是 GWLP_USERDATA 单元的所有者?

众所周知,GWLP_USERDATA可用于将一些指针大小数据与指定窗口相关联。但谁有权这样做呢?显然,如果两段代码独立执行此操作 - 一段是覆盖另一段的数据 - 所以必须只有一个所有者。但必须明确确定一个一般规则——谁是GWLP_USERDATA细胞的所有者?它属于谁?

可以是两个内部一致的协议:

  1. 创建窗口的代码是所有者。属于窗口的创建者
  2. 实现窗口类的代码。属于窗口类实现者

必须使用这两种解决方案中的哪一种?

1. 来自MSDN

GWLP_USERDATA

设置与窗口关联的用户数据。此数据旨在供创建窗口的应用程序使用。它的值最初为零。

怎么需要明白This data is intended for use by the application that created the window

所以调用CreateWindowEx, CreateDialogParam,DialogBoxParam等的代码-只有这个代码可以使用GWLP_USERDATA. 由此也得出窗口类实现者不能使用GWLP_USERDATA. GWLP_USERDATA用于将类的实例绑定到指定窗口的大量示例是不正确的。管理应用程序状态- 官方 MSDN 示例,GWLP_USERDATA用于将数据结构绑定到窗口的位置不正确?!

SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);

在这条规则下是错误的。

有什么可以说支持这个版本的?我检查了不同的 Windows 版本(从 xp 到 win10) - 我如何看到所有 Windows 内置窗口类(WC_*和其他)使用

SetWindowLongPtr(hwnd, 0, …

windows winapi

6
推荐指数
0
解决办法
439
查看次数

_InterlockedCompareExchange 优化

看看这段代码

extern "C" long _InterlockedCompareExchange(long volatile * _Destination, long _Exchange, long _Comparand);

#define MAGIC 1

// Unlike InterlockedIncrement this function not increment from 0 to 1, but return FALSE

bool TryLock(long* pLock)
{
    long Value = *pLock, NewValue;

    for ( ; Value; Value = NewValue)
    {
        NewValue = _InterlockedCompareExchange(pLock, Value + 1, Value);

        if (
#if MAGIC
            NewValue == Value
#else
            Value == NewValue
#endif
            ) return true;
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

如果设置有#define MAGIC 0什么改变吗?按想法一定不是。但是如果使用CL.EXE64 位编译器,如果我们更改 …

c optimization x86 assembly x86-64

5
推荐指数
1
解决办法
197
查看次数

标签 统计

c ×2

winapi ×2

assembly ×1

drag-and-drop ×1

optimization ×1

windows ×1

x86 ×1

x86-64 ×1