PDA

View Full Version : سوال: گرفتن پیغام تغییر کلیبرد



A_Salimi
سه شنبه 18 فروردین 1388, 23:07 عصر
سلام

آیا راهی وجود دارد که بتوان پیغام COPY ، CUT و در کل پیغام تغییر کلیبرد را دریافت کرد ؟


با تشکر

Nima_NF
سه شنبه 18 فروردین 1388, 23:53 عصر
اگر منظورتان موارد داخل Clipboard، خواند و نوشتن محتویات آن ها هست توابع زیر برای این کار هست:
OpenClipboard
EmptyClipboard
GetClipboardViewer
GetClipboardOwner

SetClipboardData
GetClipboardData

A_Salimi
چهارشنبه 19 فروردین 1388, 01:11 صبح
منظورم هر تغییری در کلیبرد است .یعنی میخواهم هروقت تغییری در آن ایجاد شد یک پیغام به برنامه من فرسناده شود.(مثلا شاید بخواهم یک سرویس بنویسم که از یک فولدر خاص محافظت کند و هر وقت کپی شد کلیبرد را خالی کند).

Nima_NF
چهارشنبه 19 فروردین 1388, 02:47 صبح
برای این کار برنامه شما باید یک Clipboard Viewer شود.
با استفاده از SetClipboardViewer پنجره کنونی را به Viewer تبدیل می کنید (در پیام WM_CREATE در هنگام شروع برنامه یا همان OnCreate در MFC) و پنجره بعد از آن می تواند پیام WM_DRAWCLIPBOARD را دریافت کند، این پیام وقتی ارسال می شود که اطلاعاتی در Clipboard وارد می شود و شما می توانید در آن با توجه به نوعی که واردش می شود آن را پردازش کنید (text باشد یا فایل یا ...).

WM_CHANGECBCHAIN نیز باید با SendMessage تنظیم شود تا اگر پنجره دیگری خودش را از حالت Clipboard Viewer خارج کرد آن را حذف کنیم. (از پارامتر های این پیام استفاده می کنیم).




// OnCreate
HWND hwndNextViewer;
hwndNextViewer = SetClipboardViewer () ;

سپس در پیام WM_DRAWCLIPBOARD (همان OnDrawClipboard در MFC) مثلا به این شکل:



TCHAR fileName[256];
HDROP hdrop;

//--------------
OpenClipboard (hwnd) ;

if (hwndNextViewer)
::SendMessage (hwndNextViewer, WM_CHANGECBCHAIN, 0, 0) ; // It is necessary

hdrop = (HDROP) ::GetClipboardData (CF_HDROP) ;
::DragQueryFile(hdrop,0 ,fileName, sizeof(fileName)/2);

// use fileName here, for example: fileName = C:\myfile.dat

CloseClipboard () ;

با DragQueryFile و فلگ CF_HDROP برای کپی کردن فایل ها استفاده می کنیم و fileName مسیر فایل را می دهد.
مثلا وقتی فایل همان مورد نظر بود می توانید با EmptyClipboard آن را خالی کنید.

برای نوشته ها باید از CF_TEXT استفاده کنید. و ...

برای پیام WM_CHANGECBCHAIN هم به این شکل(همان OnChangeCbChain):





if ((HWND) hWndRemove == hwndNextViewer)
hwndNextViewer = (HWND) hWndAfter ;

else if (hwndNextViewer)
::SendMessage (hwndNextViewer, WM_CHANGECBCHAIN, hWndRemove, hWndAfter) ;



- در هنگام بستن برنامه هم باید ChangeClipboardChain را فراخوانی کنید.

meysamg_alone
چهارشنبه 19 فروردین 1388, 17:20 عصر
WM_DRAWCLIPBOARD
این روال داخل win32 هم قابل دست رسی هست اگه هست چه جوری یعنی همین WM_DRAWCLIPBOARD را داخل switch مسج بزاریم میشه یا نه

Nima_NF
پنج شنبه 20 فروردین 1388, 00:05 صبح
WM_DRAWCLIPBOARD
این روال داخل win32 هم قابل دست رسی هست اگه هست چه جوری یعنی همین WM_DRAWCLIPBOARD را داخل switch مسج بزاریم میشه یا نه
بله، فقط باید در WM_CREATE همان SetClipboardViewer را با Hwnd پنجره فراخوانی کنید:



HWND hwndNextViewer;
hwndNextViewer = SetClipboardViewer ( hwnd ) ;

A_Salimi
جمعه 04 اردیبهشت 1388, 14:44 عصر
روش خیلی جالبی بود.

زمانی که در OnCreat از SetClipboardViewer استفاده میکردم برنامه در ابتدای اجرا با یک پیغام مواجه میشد که به این دلیل آن را در OnInitDialog قرار دادم.


آیا میشود از این روش در برنامه نویسی سرویس هم استفاده کرد ؟چون ما در سرویس هیچ پنجره ایی نداریم چطور میتوانیم از Event هایی که در اینجا داریم در آنجا هم استفاده کنیم ؟

Nima_NF
جمعه 04 اردیبهشت 1388, 19:05 عصر
سرویس ها قابلیتی دارند که با ایجاد تغییر در فلگ های آن هنگام ساخت سرویس، می توانید کاری کنید که سرویس GUI داشته باشد یا بتواند با کاربر تعامل داشته باشد.

مثلا در CreateService فلگ SERVICE_INTERACTIVE_PROCESS را انتخاب کنید و lpServiceStartName را NULL .

جزییات بیشتری از نحوه دقیق انجام این کار ندارم، لذا در صورت نیاز "Interactive Services" را جستجو کنید