繁体   English   中英

处理正在运行的Windows控制台应用程序中的拖放文件

[英]Handling drag and drop files in a running Windows console application

首先,澄清一点,我不是问如何将文件拖放到exe的图标上。 我想知道如何处理拖放到已经运行的 win32控制台应用程序。 我也没有问如何通过Windows消息泵处理基于WinMain的应用程序内部的拖放。 我想在一个程序中使用入口点int main()没有WndProc(尚未)或任何东西。

那就是说,我想知道我的目标是否可以实现(并希望它是)。

我有一个在控制台窗口中运行的服务器应用程序。 由于代码库很大并且有许多奇怪的耦合,它是一个“仅输出”控制台,适用于所有密集目的。 尽管如此,我仍然可以处理按键等操作,因为我有更新循环滴答声。 我希望能够将完整命令(使用自定义语法)的文件拖放到我正在运行的应用程序中并让它处理它们。

这可能吗? 我在想,我可能会得到一个指向控制台HWND的指针(希望这是一个东西?),然后可能将该窗口子类化为使用自定义WndProc来监听WM_DROPFILES消息。

我从来没有真正尝试在int main()程序中设置windows消息的处理而不是WinMain程序,但我希望它在某种程度上可行。

任何帮助将不胜感激! 奇怪的解决方案很好。

AFAIK,控制台窗口默认情况下不支持拖放。 您始终可以使用自己的消息循环创建自己的单独弹出窗口,以便用户可以将项目拖动到其上。

要在控制台窗口本身上使用拖放操作,请尝试使用GetConsoleWindow()来获取控制台HWND,然后执行以下任一操作:

  1. 使用SetWindowLong/Ptr()SetWindowSubClass()对HWND进行子类化,然后使用DragAcceptFiles()注册HWND以开始接收WM_DROPFILES消息。 请务必再次调用DragAcceptFiles()以停止接收消息,然后在退出应用程序之前取消挂钩子类。

  2. 实现IDropTarget接口,然后使用RegisterDragDrop()注册HWND以开始接收通知。 务必在退出应用程序之前调用RevokeDragDrop()

WM_DROPFILES更容易编码,但IDropTarget在处理虚拟项目和物理文件时更加灵活。

#include <vector>
#include <string>
#include <iostream>
#include <conio.h>

int main()
{
    std::cout << "Please drop files and press [Enter] when done ...\n";

    std::vector< std::string > files;

    for( int ch = _getch(); ch != '\r'; ch = _getch() ) {

        std::string file_name;

        if( ch == '\"' ) {  // path containing spaces. read til next '"' ...

            while( ( ch = _getch() ) != '\"' )
                file_name += ch;

        } else { // path not containing spaces. read as long as chars are coming rapidly.

            file_name += ch;

            while( _kbhit() )
                file_name += _getch();
        }

        files.push_back( file_name );
    }

    std::cout << "You dropped these files:\n";

    for( auto & i : files )
        std::cout << i << '\n';
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM