ホームに戻る
ブラウザからURLをドラッグアンドドロップ
#include <windows.h>
#include <windowsx.h>
#define ID_EDIT 1000
// ウィンドウプロシージャの宣言(ウィンドウの動作を規定)
LRESULT CALLBACK WndProc(
HWND hwnd, //ウィンドウハンドル(void型ポインタ)
UINT message, //メッセージ識別番号(unsigned int)
WPARAM wParam, //(32ビットlong)
LPARAM lParam); //(32ビットlong)
//エディット用の文字列追加関数
void Edit_AddString(HWND hwnd, char *string);
//エディットを1個宣言
HWND hEdit;
//文字列の保管用
static char txt[57];
//メイン関数
int APIENTRY WinMain(
HINSTANCE hInstance, //インスタンスのハンドル
HINSTANCE hPreInstance, //以前のインスタンスハンドル
LPSTR cmdLine, //コマンド行の文字列
int cmdShow) //ウィンドウの表示状態
{
//ウィンドウクラスの宣言
WNDCLASS wd;
//ウィンドウクラス名
char *wdName = "window00";
//ウィンドウ登録のためのループ
if (!hPreInstance) {
//ウィンドウスタイル
wd.style = CS_HREDRAW | CS_VREDRAW; //幅、高さの変化に対し再描画する
//ウィンドウプロシージャ
wd.lpfnWndProc = (WNDPROC)WndProc;
//クラスの予備のメモリ領域
wd.cbClsExtra = 0;
//ウィンドウの予備のメモリ領域
wd.cbWndExtra = 0;
//プログラムのインスタンスハンドル
wd.hInstance = hInstance;
//アイコンのハンドル
wd.hIcon = NULL;
//カーソルのハンドル
wd.hCursor = LoadCursor(NULL, IDC_ARROW);
//バックグラウンドのブラシのハンドル
wd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
//メニュー名
wd.lpszMenuName = NULL;
//クラス名
wd.lpszClassName = wdName;
//ウィンドウの登録(成功 非0、失敗 0)
if (!RegisterClass(&wd))
return FALSE;
}
//ウィンドウの生成(ハンドルを form00 とする)
HWND form00 = CreateWindowEx(
NULL, //拡張スタイル(なし)
wdName, //ウィンドウクラス名
"window", //ウィンドウの名前
WS_OVERLAPPEDWINDOW, //ウィンドウスタイル(オーバーラップ型)
CW_USEDEFAULT, //ウィンドウのX座標(ディフォルト)
CW_USEDEFAULT, //ウィンドウのY座標(ディフォルト)
200, //ウィンドウの幅(80に設定)
100, //ウィンドウの高さ(50に設定)
NULL, //親ウィンドウ(この場合自身が親)
NULL, //メニュー(なし)
hInstance, //プログラムのハンドル
NULL); //予備パラメータ
//ウィンドウの表示
ShowWindow(form00, cmdShow);
//ウィンドウの更新
UpdateWindow(form00);
//イベントのループ
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// ドラッグ・アンド・ドロップを登録するためのクラス
// 注:必ず new で作成すること
class CDropTarget : public IDropTarget
{
public:
CDropTarget():URLDrop(NULL),_RefCount(1),_DataObject(NULL),pData(NULL){};
~CDropTarget(){};
virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
virtual HRESULT __stdcall DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect );
virtual HRESULT __stdcall DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
virtual HRESULT __stdcall DragLeave();
virtual HRESULT __stdcall Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
// コールバック関数
void __fastcall (*URLDrop)(char* url_name);
// URL名を得る
char *getName(){return (char *)pData;}
private:
LONG _RefCount;
IDataObject *_DataObject;
void *pData;
};
HRESULT __stdcall CDropTarget::QueryInterface(const IID& iid, void** ppv)
{
HRESULT hr;
if(iid == IID_IDropTarget || iid == IID_IUnknown){
hr = S_OK;
*ppv = (void*)this;
AddRef();
}
else{
hr = E_NOINTERFACE;
*ppv = 0;
}
return hr;
}
ULONG __stdcall CDropTarget::AddRef()
{
InterlockedIncrement(&_RefCount);
return (ULONG)_RefCount;
}
ULONG __stdcall CDropTarget::Release()
{
ULONG ret = (ULONG)InterlockedDecrement(&_RefCount);
if(ret == 0){
delete this;
}
return (ULONG)_RefCount;
}
HRESULT __stdcall CDropTarget::DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL ptl, DWORD* pdwEffect)
{
_DataObject = pDataObject;
return DragOver(grfKeyState, ptl, pdwEffect);
}
HRESULT __stdcall CDropTarget::DragOver(DWORD grfKeyState, POINTL ptl, DWORD* pdwEffect)
{
*pdwEffect = DROPEFFECT_LINK;
return S_OK;
}
HRESULT __stdcall CDropTarget::DragLeave()
{
_DataObject = NULL;
return S_OK;
}
HRESULT __stdcall CDropTarget::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL ptl, DWORD* pdwEffect)
{
FORMATETC sFormatEtc;
STGMEDIUM sStgMedium;
if(_DataObject == NULL){
return 0;
}
::ZeroMemory(&sFormatEtc,sizeof(FORMATETC));
sFormatEtc.cfFormat = CF_TEXT;
sFormatEtc.dwAspect = DVASPECT_CONTENT;
sFormatEtc.lindex = -1;
sFormatEtc.tymed = TYMED_HGLOBAL;
_DataObject->GetData(&sFormatEtc,&sStgMedium);
pData = GlobalLock(sStgMedium.hGlobal);
if(URLDrop != NULL){
URLDrop((char *)pData);
}
::GlobalUnlock(sStgMedium.hGlobal);
::ReleaseStgMedium(&sStgMedium);
return S_OK;
}
// ドラッグ・アンド・ドロップ時に呼ばれる
void __fastcall URLDrop(char* url_name){
Edit_AddString(hEdit, (LPTSTR)url_name);
Edit_AddString(hEdit, (LPTSTR)"\r\n");
}
// ウィンドウプロシージャ(ウィンドウの動作を規定)
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
//インスタンスハンドルを得る
HINSTANCE hInst;
hInst = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
//ウィンドウのサイズ取得用
RECT r;
static CDropTarget *DTarget;
switch (message) {
//ウィンドウを表示するとき処理
case WM_CREATE:
// ドラッグ・アンド・ドロップを登録
OleInitialize(NULL);
DTarget = new CDropTarget();
DTarget->URLDrop = URLDrop;
RegisterDragDrop(hwnd, (IDropTarget*)DTarget);
//エディットの表示
GetClientRect(hwnd, &r);
hEdit = CreateWindow(
"EDIT",
NULL,
WS_CHILD | WS_VISIBLE |
ES_WANTRETURN | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL |
ES_AUTOHSCROLL | WS_HSCROLL,
0, 0,
r.right, r.bottom,
hwnd,
(HMENU)ID_EDIT,
hInst,
NULL);
SendMessage(hEdit, EM_SETLIMITTEXT, (WPARAM)1024*64, 0);
break;
//ウィンドウサイズ変更に対する処理
case WM_SIZE:
GetClientRect(hwnd, &r);
MoveWindow(hEdit
,r.left
,r.top
,r.right
,r.bottom
,TRUE); //再描画のフラグ
break;
//ウィンドウを破壊する時の処理
case WM_DESTROY:
delete(DTarget);
//メイン関数のループを終了
PostQuitMessage(0);
break;
//デフォルトの処理に対してデフォルトの処理を返す
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return NULL;
}
//エディット用の文字列追加関数
// Edit_ のために windowsx.h が必要
void Edit_AddString(HWND hwnd, char *string)
{
//エディタ中の文字列の長さを得る
int length = Edit_GetTextLength(hwnd);
//エディタの文字列の末尾に移動
Edit_SetSel(hwnd, length, length);
//文字列を追加
Edit_ReplaceSel(hwnd, string);
}