Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 872

/ вопрос открыт /

Здравствуйте, эксперты!
Как определить что содержимое буфера обмена изменилось, но не по нажатию кнопки и т.п., а как только оно изменилось! Для последующей его очистки
Т.е. во время работы программы буфер должен постоянно быть пустым...
А лучше, как его заблокировать? и разблокировать потом :-)

20.08.1987 Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: 20.08.1987 (статус: Посетитель)
Вопрос отправлен: 24 августа 2007, 22:17
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Матвеев Игорь Владимирович

Здравствуйте, 20.08.1987!
Первое: установить обработчик изменения буфера обмена, при изменени Вам будут приходить сообщения WM_CHANGECBCHAIN / WM_DRAWCLIPBOARD. Пример см. в приложении.

Второе: Очищать буфер при изменении, либо помещать туда свои данные, скажем строку "Копировать запрещено". Непосредственно блокировать буфер нельзя, хотя можно организовать перехват API, ответственных за копирование, но это сложно, долго, неудобно, неуниверсально и глупо.

Приложение:
  1. {
  2. An application can be notified of changes in the data stored in the
  3. Windows clipboard by registering itself as a Clipboard Viewer.
  4.  
  5. Clipboard viewers use two API calls and several messages to communicate
  6. with the Clipboard viewer chain. SetClipboardViewer adds a window to the
  7. beginning of the chain and returns a handle to the next viewer in the chain.
  8. ChangeClipboardChain removes a window from the chain. When a clipboard change occurs,
  9. the first window in the clipboard viewer chain is notified via the WM_DrawClipboard
  10. message and must pass the message on to the next window. To do this, our application
  11. must store the next window along in the chain to forward messages to and also respond
  12. to the WM_ChangeCBChain message which is sent whenever any other clipboard viewer on
  13. the system is added or removed to ensure the next window along is valid.
  14. }
  15.  
  16.  
  17. unit Unit1;
  18.  
  19. interface
  20.  
  21. uses
  22. Windows, Messages, Forms, Classes, Controls, StdCtrls;
  23.  
  24. type
  25. TForm1 = class(TForm)
  26. Button1: TButton;
  27. Button2: TButton;
  28. procedure Button1Click(Sender : TObject);
  29. procedure Button2Click(Sender : TObject);
  30. procedure FormCreate(Sender : TObject);
  31. procedure FormDestroy(Sender : TObject);
  32. private
  33. FNextClipboardViewer: HWND;
  34. procedure WMChangeCBChain(var Msg : TWMChangeCBChain); message WM_CHANGECBCHAIN;
  35. procedure WMDrawClipboard(var Msg : TWMDrawClipboard); message WM_DRAWCLIPBOARD;
  36. end;
  37.  
  38. var
  39. Form1 : TForm1;
  40.  
  41. implementation
  42.  
  43. {$R *.DFM}
  44.  
  45. procedure TForm1.FormCreate(Sender : TObject);
  46. begin
  47. { Initialize variable }
  48. FNextClipboardViewer := 0;
  49. end;
  50.  
  51.  
  52. procedure TForm1.Button1Click(Sender : TObject);
  53. begin
  54. if FNextClipboardViewer <> 0 then
  55. MessageBox(0, 'This window is already registered!', nil, 0)
  56. else
  57. { Add to clipboard chain }
  58. FNextClipboardViewer := SetClipboardViewer(Handle);
  59. end;
  60.  
  61.  
  62. procedure TForm1.Button2Click(Sender : TObject);
  63. begin
  64. { Remove from clipboard chain }
  65. ChangeClipboardChain(Handle, FNextClipboardViewer);
  66. FNextClipboardViewer := 0;
  67. end;
  68.  
  69.  
  70. procedure TForm1.WMChangeCBChain(var Msg : TWMChangeCBChain);
  71. begin
  72. inherited;
  73. { mark message as done }
  74. Msg.Result := 0;
  75. { the chain has changed }
  76. if Msg.Remove = FNextClipboardViewer then
  77. { The next window in the clipboard viewer chain had been removed. We recreate it. }
  78. FNextClipboardViewer := Msg.Next
  79. else
  80. { Inform the next window in the clipboard viewer chain }
  81. SendMessage(FNextClipboardViewer, WM_CHANGECBCHAIN, Msg.Remove, Msg.Next);
  82. end;
  83.  
  84.  
  85. procedure TForm1.WMDrawClipboard(var Msg : TWMDrawClipboard);
  86. begin
  87. inherited;
  88. { Clipboard content has changed }
  89. try
  90. MessageBox(0, 'Clipboard content has changed!', 'Clipboard Viewer', MB_ICONINFORMATION);
  91. finally
  92. { Inform the next window in the clipboard viewer chain }
  93. SendMessage(FNextClipboardViewer, WM_DRAWCLIPBOARD, 0, 0);
  94. end;
  95. end;
  96.  
  97.  
  98. procedure TForm1.FormDestroy(Sender : TObject);
  99. begin
  100. if FNextClipboardViewer <> 0 then
  101. begin
  102. { Remove from clipboard chain }
  103. ChangeClipboardChain(Handle, FNextClipboardViewer);
  104. FNextClipboardViewer := 0;
  105. end;
  106. end;
  107.  
  108. end.


Ответ отправил: Матвеев Игорь Владимирович (статус: Студент)
Время отправки: 25 августа 2007, 05:39
Оценка за ответ: 5


Мини-форум вопроса

Мини-форум пуст.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:29
Выполнено за 0.02 сек.