RichEdit如何在BC或Delphi程序中接受文件拖放?
How RichEdit can accept file drag & dropping in BCB or Delphi program?
我正在编写一个程序,可以将文本文件拖放到表单上以通过 RichEdit 显示和编辑它。
我已经使用 ChangeWindowMessageFilterEx 来确保 WM_DROPFILES 和 WM_COPYDATA 可以被我的主窗体接收:
ChangeWindowMessageFilterEx(Handle, WM_DROPFILES, MSGFLT_ADD, NULL);
ChangeWindowMessageFilterEx(Handle, WM_COPYDATA, MSGFLT_ADD, NULL);
ChangeWindowMessageFilter(73 , MSGFLT_ADD);
并在表单创建函数中调用DragAcceptFiles(Handle, true)
。
现在拖动操作在window的任何地方都有效,但除了RichEdit,在RichEdit上拖动时光标显示一个拒绝图标。
拖动任何组件,例如。窗体上的文本编辑器、面板、组合框和按钮可以导致收到 WM_DROPFILES 消息,但 RichEdit 除外。
其实我确定RichEdit是可以拖拽文件的,因为我去年写过代码,但是我丢了源码忘记了。我现在正在尝试重建同一个。
这是the google drive download link to the executable file that I have finished last year. And here is the github url我目前正在编写的未完成的源代码。
感谢您的收看
我不知道为什么 TRichEdit
在使用消息映射时没有收到 WM_DROPFILES
,但是你可以处理 TRichEdit
的 WindowProc
。
一个可能的实现可能如下所示:
- 在您的表单上添加
TRichEdit
修改头文件
private:
TWndMethod OldWindowProc;
void __fastcall NewWindowProc(TMessage& Msg);
添加实现
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
OldWindowProc = RichEdit1->WindowProc;
RichEdit1->WindowProc = NewWindowProc;
DragAcceptFiles(RichEdit1->Handle, true);
}
void __fastcall TForm1::NewWindowProc(TMessage& Msg)
{
switch (Msg.Msg) {
case WM_DROPFILES:
{
HDROP DropH = (HDROP)Msg.WParam;
int droppedFileCount = DragQueryFile(DropH, 0xFFFFFFFF, NULL, 0);
TStringList* Buffer = new TStringList();
for (int i = 0; i < droppedFileCount; i++) {
int fileNameLength = DragQueryFile(DropH, i, NULL, 0);
String FileName;
FileName.SetLength(fileNameLength);
DragQueryFile(DropH, i, FileName.w_str(), fileNameLength + 1);
Buffer->LoadFromFile(FileName);
RichEdit1->Lines->AddStrings(Buffer);
RichEdit1->Lines->Add("");
}
delete Buffer;
DragFinish(DropH);
Msg.Result = 0;
break;
}
case CM_RECREATEWND:
DragAcceptFiles(RichEdit1->Handle, true);
break;
default:;
}
OldWindowProc(Msg);
}
我正在编写一个程序,可以将文本文件拖放到表单上以通过 RichEdit 显示和编辑它。
我已经使用 ChangeWindowMessageFilterEx 来确保 WM_DROPFILES 和 WM_COPYDATA 可以被我的主窗体接收:
ChangeWindowMessageFilterEx(Handle, WM_DROPFILES, MSGFLT_ADD, NULL);
ChangeWindowMessageFilterEx(Handle, WM_COPYDATA, MSGFLT_ADD, NULL);
ChangeWindowMessageFilter(73 , MSGFLT_ADD);
并在表单创建函数中调用DragAcceptFiles(Handle, true)
。
现在拖动操作在window的任何地方都有效,但除了RichEdit,在RichEdit上拖动时光标显示一个拒绝图标。
拖动任何组件,例如。窗体上的文本编辑器、面板、组合框和按钮可以导致收到 WM_DROPFILES 消息,但 RichEdit 除外。
其实我确定RichEdit是可以拖拽文件的,因为我去年写过代码,但是我丢了源码忘记了。我现在正在尝试重建同一个。
这是the google drive download link to the executable file that I have finished last year. And here is the github url我目前正在编写的未完成的源代码。
感谢您的收看
我不知道为什么 TRichEdit
在使用消息映射时没有收到 WM_DROPFILES
,但是你可以处理 TRichEdit
的 WindowProc
。
一个可能的实现可能如下所示:
- 在您的表单上添加
TRichEdit
修改头文件
private: TWndMethod OldWindowProc; void __fastcall NewWindowProc(TMessage& Msg);
添加实现
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { OldWindowProc = RichEdit1->WindowProc; RichEdit1->WindowProc = NewWindowProc; DragAcceptFiles(RichEdit1->Handle, true); } void __fastcall TForm1::NewWindowProc(TMessage& Msg) { switch (Msg.Msg) { case WM_DROPFILES: { HDROP DropH = (HDROP)Msg.WParam; int droppedFileCount = DragQueryFile(DropH, 0xFFFFFFFF, NULL, 0); TStringList* Buffer = new TStringList(); for (int i = 0; i < droppedFileCount; i++) { int fileNameLength = DragQueryFile(DropH, i, NULL, 0); String FileName; FileName.SetLength(fileNameLength); DragQueryFile(DropH, i, FileName.w_str(), fileNameLength + 1); Buffer->LoadFromFile(FileName); RichEdit1->Lines->AddStrings(Buffer); RichEdit1->Lines->Add(""); } delete Buffer; DragFinish(DropH); Msg.Result = 0; break; } case CM_RECREATEWND: DragAcceptFiles(RichEdit1->Handle, true); break; default:; } OldWindowProc(Msg); }