summaryrefslogtreecommitdiff
path: root/include/delphi/m_popup.inc
blob: 15a2c66696523d5392d92bd09cd8b80912483d14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
{
===============================================================================
                                Popup plugin
Plugin Name: Popup
Plugin authors: Luca Santarelli aka hrk (hrk@users.sourceforge.net)
                Victor Pavlychko (nullbie@gmail.com)
===============================================================================
The purpose of this plugin is to give developers a common "platform/interface"
to show Popups. It is born from the source code of NewStatusNotify, another
plugin I've made.

Remember that users *must* have this plugin enabled, or they won't get any
popup. Write this in the requirements, do whatever you wish ;-)... but tell
them!
===============================================================================
}

{$IFNDEF M_POPUP}
{$DEFINE M_POPUP}

{
NOTE! Since Popup 1.0.1.2 there is a main meun group called "Popups" where I
have put a "Enable/Disable" item. You can add your own "enable/disable" items
by adding these lines before you call MS_CLIST_ADDMAINMENUITEM:
mi.pszPopupName = Translate("Popups");
mi.position = 0; //You don't need it and it's better if you put it to zero.
}

const POPUP_VERSION = $02010003;

const
  MAX_CONTACTNAME = 2048;
  MAX_SECONDLINE  = 2048;
  MAX_ACTIONTITLE = 64;

//  POPUP_USE_SKINNED_BG = $FFFFFFFF;

// Popup Action flags
  PAF_ENABLED = $01; // Actions is enabled. You may store one global
                     // action set and toggle some items depending on
                     // popup you are requesting

type
  PPOPUPACTION = ^TPOPUPACTION;
  TPOPUPACTION = record
    cbSize  :int;    // sizeof(POPUPACTION)
    lchIcon :HICON;  // Action Icon
    // Action title text. Please use module name as prefix
    // (e.g. "Popup Plus/Dismiss Popup") and don't translate
    lpzTitle:array [0..MAX_ACTIONTITLE-1] of AnsiChar;
    flags   :DWORD;  // set of PAF_* flags
    wParam  :WPARAM; // wParam for UM_POPUPACTION message
    lParam  :LPARAM; // lParam for UM_POPUPACTION message
  end;

type
  PPOPUPDATA = ^TPOPUPDATA;
  TPOPUPDATA = record
    lchContact      : THANDLE;
    lchIcon         : HICON;
    lpszContactName : array [0..MAX_CONTACTNAME-1] of AnsiChar;
    lpszText        : array [0..MAX_SECONDLINE -1] of AnsiChar;
    colorBack       : COLORREF;
    colorText       : COLORREF;
    PluginWindowProc: pointer;
    PluginData      : Pointer;
    iSeconds        : int;      // Custom delay time in seconds.
                                // -1 means "forever", 0 means = 'default time".
{ Data prior $02010003 version
    lpzClass        : PAnsiChar;    // Popup class. Used with skinning. See Popup/AddClass for details
    skinBack        : COLORREF; // Background color for colorizable skins
    cZero: array [0..15-SizeOf(PAnsiChar)-SizeOf(COLORREF)] of byte;
}
  // you *MUST* pass APT_NEWDATA flag for services to take care of this data
    hReserved       : THANDLE;  // Reserved. Must be NULL
    actionCount     : int;      // Amount of passed actions
    lpActions       : PPOPUPACTION; // Popup Actions
    icbSize         : int;      // struct size for future
  end;

type
  PPOPUPDATAW = ^TPOPUPDATAW;
  TPOPUPDATAW = record
    lchContact      : THANDLE;
    lchIcon         : HICON;
    lpwzContactName : array [0..MAX_CONTACTNAME-1] of WideChar;
    lpwzText        : array [0..MAX_SECONDLINE -1] of WideChar;
    colorBack       : COLORREF;
    colorText       : COLORREF;
    PluginWindowProc: Pointer;  // must be a window procedure using stdcall
    PluginData      : Pointer;
    iSeconds        : int;      // Custom delay time in seconds.
                                //  -1 means = 'forever", 0 means = 'default time".
{ Data prior $02010003 version
    cZero: array [0..15] of AnsiChar; //16 unused bytes which may come useful in the future.
}
  // you *MUST* pass APT_NEWDATA flag for services to take care of this data
    hReserved       : THANDLE;  // Reserved. Must be NULL
    actionCount     : int;      // Amount of passed actions
    lpActions       : PPOPUPACTION; // Popup Actions
    icbSize         : int;      // struct size for future
  end;

{
  When you call MS_POPUP_ADDPOPUP, my plugin will check if the given POPUPDATA
structure is filled with acceptable values. If not, the data will be rejected
and no popup will be shown.

- lpzText should be given, because it's really bad if a user chooses to have the
second line displayed and it's empty :-) Just write it and let the user choose
if it will be displayed or not.

- PluginWindowProc is a WNDPROC address you have to give me. Why? What? Where?
Calm down 8) My plugin will take care of the creation of the popup, of the
destruction of the popup, of the come into view and the hiding of the popup.
Transparency, animations... all this stuff.
  My plugin will not (as example) open the MessageWindow when you left click on
a popup. Why? Because I don't know if your popup desires to open the
MessageWindow :)))) This means that you need to make a WNDPROC which takes care
of the WM_messages you need.
  For example, WM_COMMAND or WM_CONTEXTMENU or WM_LMOUSEUP or whatever.
  At the end of your WNDPROC remember to "return DefWindowProc(hwnd, msg,
wParam, lParam);" When you process a message that needs a return value (an
example could be WM_CTLCOLORSTATIC, but you don't need to catch it 'cause it's
my plugin's job), simply return the nedeed value. :)
The default WNDPROC does nothing.

- PluginData is a pointer to a void, which means a pointer to anything. You can
make your own structure to store the data you need (example: a status
information, a date, your name, whatever) and give me a pointer to that struct.
You will need to destroy that structure and free the memory when the Popup is
going to be destroyed. You'll know this when you receive a UM_FREEPLUGINDATA.
The name tells it all: free your own plugin data.

Appendix A: Messages my plugin will handle and your WNDPROC will never see.
WM_CREATE, WM_DESTROY, WM_TIMER, WM_ERASEBKGND
WM_CTLCOLOR* [whatever it may be: WM_CTLCOLORDLG, WM_CTLCOLORSTATIC...]
WM_PAINT, WM_PRINT, WM_PRINTCLIENT
}

const
{
  Creates, adds and shows a popup, given a (valid) POPUPDATA structure pointer.
  wParam = (WPARAM)(*POPUPDATA)PopupDataAddress
  lParam = 0
  Returns: > 0 on success, 0 if creation went bad, -1 if the PopupData contained unacceptable values.
  NOTE: it returns -1 if the PopupData was not valid, if there were already too many popups, if the module was disabled.
  Otherwise, it can return anything else...

Popup Plus 2.0.4.0+
You may pass additional creation flags via lParam:
  APF_RETURN_HWND ....... function returns handle to newly created popup window (however this calls are a bit slower)
  APF_CUSTOM_POPUP ...... new popup is created in hidden state and doesn't obey to popup queue rules.
              you may control it via UM_* messages and custom window procedure
  APF_NO_HISTORY ........ do not log this popup in popup history (useful for previews)
  APF_NO_POPUP .......... do not show popup. this is useful if you want popup yo be stored in history only
  APF_NEWDATA ........... use new version of POPUPDATAEX/POPUPDATAW structs
}
  APF_RETURN_HWND  = 1;
  APF_CUSTOM_POPUP = 2;
  APF_NO_HISTORY   = 4;
  APF_NO_POPUP     = 8;
  APF_NEWDATA      = $10;

  MS_POPUP_ADDPOPUPW:PAnsiChar = 'Popup/AddPopupW';
  MS_POPUP_ADDPOPUP :PAnsiChar = 'Popup/AddPopupEx';

{
  Returns the handle to the contact associated to the specified PopupWindow.
  You will probably need to know this handle inside your WNDPROC. Exampole: you want to open the MessageWindow. :-)
  Call MS_POPUP_GETCONTACT on the hWnd you were given in the WNDPROC.
  wParam = (WPARAM)(HWND)hPopupWindow
  lParam = 0;
  Returns: the HANDLE of the contact. Can return NULL, meaning it's the main contact. -1 means failure.
}
  MS_POPUP_GETCONTACT:PAnsiChar = 'Popup/GetContact';

{
  wParam = hPopupWindow
  lParam = PluginDataAddress;
  Returns: the address of the PLUGINDATA structure. Can return NULL, meaning nothing was given. -1 means failure.
  IMPORTANT NOTE: it doesn't seem to work if you do:
  CallService(..., (LPARAM)aPointerToAStruct);
  and then use that struct.
  Do this, instead:
  aPointerToStruct = CallService(..., (LPARAM)aPointerToAStruct);
  and it will work. Just look at the example I've written above (PopupDlgProc).
}
  MS_POPUP_GETPLUGINDATA:PAnsiChar = 'Popup/GetPluginData';

{
  wParam = 0
  lParam = 0
  Returns: 0 if the user has chosen not to have the second line, 1 if he choose to have the second line.
}
  MS_POPUP_ISSECONDLINESHOWN:PAnsiChar = 'Popup/IsSecondLineShown';

{
  Requests an action or an answer from Popup module.
  wParam = (WPARAM)wpQuery
  returns 0 on success, -1 on error, 1 on stupid calls ;-)
}
  PUQS_ENABLEPOPUPS  = 1; // returns 0 if state was changed, 1 if state wasn't changed
  PUQS_DISABLEPOPUPS = 2; // " "
  PUQS_GETSTATUS     = 3; // Returns 1 if popups are enabled, 0 if popups are disabled.

  MS_POPUP_QUERY:PAnsiChar = 'Popup/Query';

{
  UM_FREEPLUGINDATA
  wParam = lParam = 0. Process this message if you have allocated your own memory. (i.e.: POPUPDATA.PluginData != NULL)
}
  UM_FREEPLUGINDATA  = (WM_USER + $200);

{
  UM_DESTROYPOPUP
  wParam = lParam = 0. Send this message when you want to destroy the popup, or use the function below.
}
  UM_DESTROYPOPUP = (WM_USER + $201);

{
  UM_INITPOPUP
  wParam = (WPARAM)(HWND)hPopupWindow (but this is useless, since I'll directly send it to your hPopupWindow
  lParam = 0.
  This message is sent to the Popup when its creation has been finished, so POPUPDATA (and thus your PluginData) is reachable.
  Catch it if you needed to catch WM_CREATE or WM_INITDIALOG, which you'll never ever get in your entire popup-life.
  Return value: if you process this message, return 0. If you don't process it, return 0. Do whatever you like ;-)
}
  UM_INITPOPUP = (WM_USER + $202);

{
  wParam = hPopupWindow
  lParam = lpzNewText
  returns: > 0 for success, -1 for failure, 0 if the failure is due to second line not being shown. (but you could call PUIsSecondLineShown() before changing the text...)
  Changes the text displayed in the second line of the popup.
}
  MS_POPUP_CHANGETEXTW:PAnsiChar = 'Popup/ChangetextW';

{
  wParam = (WPARAM)(HWND)hPopupWindow
  lParam = (LPARAM)(POPUPDATAEX*)newData
  Changes the entire popup
}
  MS_POPUP_CHANGEW:PAnsiChar = 'Popup/ChangeW';

{
 UM_CHANGEPOPUP
  This message is triggered by Change/ChangeText services. You also may post it directly :)

  wParam = Modification type
  lParam = value of type defined by wParam
}

  CPT_TEXT   = 1; // lParam = (AnsiChar *)text
  CPT_TEXTW  = 2; // lParam = (WCHAR *)text
  CPT_TITLE  = 3; // lParam = (AnsiChar *)title
  CPT_TITLEW = 4; // lParam = (WCHAR *)title
  CPT_DATAW  = 7; // lParam = (POPUPDATAW *)data
  CPT_DATA2  = 8; // lParam = (POPUPDATA2 *)data

  UM_CHANGEPOPUP = WM_USER + $0203;

{ UM_POPUPACTION
  Popup Action notification

  wParam and lParam are specified bu plugin.
  wParam = 0 is used buy popup plus internally!
}

  UM_POPUPACTION = WM_USER + $0204;

{ UM_POPUPMODIFYACTIONICON
  Modify Popup Action Icon

  wParam = (WPARAM)(LPPOPUPACTIONID)&actionId
  lParam = (LPARAM)(HICON)hIcon
}

type
  PPOPUPACTIONID = ^TPOPUPACTIONID;
  TPOPUPACTIONID = record
    wParam:WPARAM;
    lParam:LPARAM;
  end;

const
   UM_POPUPMODIFYACTIONICON = WM_USER + $0205;

const
  SM_WARNING      = $01; //Triangle icon.
  SM_NOTIFY       = $02; //Exclamation mark icon.
  SM_ERROR        = $03; //Cross icon.
{
  This is mainly for developers.
  Shows a warning message in a Popup. It's useful if you need a = 'MessageBox" like function,
  but you don't want a modal window (which will interfere with a DialogProcedure. MessageBox
  steals focus and control, this one not.
  wParam = lpzMessage
  lParam = SM_* flag
  Returns: 0 if the popup was shown, -1 in case of failure.
}
  MS_POPUP_SHOWMESSAGE :PAnsiChar = 'Popup/ShowMessage';
  MS_POPUP_SHOWMESSAGEW:PAnsiChar = 'Popup/ShowMessageW';

{ Popup/RegisterActions
Registers your action in popup action list

wParam = (WPARAM)(LPPOPUPACTION)actions
lParam = (LPARAM)actionCount

Returns: 0 if the popup was shown, -1 in case of failure.
}
  MS_POPUP_REGISTERACTIONS:PAnsiChar = 'Popup/RegisterActions';

//------------- Class API ----------------//

type
  TPOPUPCLASS = record
    cbSize          :int;
    flags           :int;
    pszName         :pAnsiChar;
    szDescription   :TChar;
    hIcon           :HICON;
    colorBack       :TCOLORREF;
    colorText       :TCOLORREF;
    PluginWindowProc:pointer;
    iSeconds        :int;
  end;
  POPUPCLASS = TPOPUPCLASS;

const
  PCF_UNICODE = $0001;

// wParam = 0
// lParam = (POPUPCLASS *)&pc
  MS_POPUP_REGISTERCLASS = 'Popup/RegisterClass';
  MS_POPUP_UNREGISTERCLASS = 'Popup/UnregisterClass';

type
  TPOPUPDATACLASS = record
	  cbSize      :int;
  	pszClassName:pAnsiChar;
		szTitle     :TChar;
		szText      :TChar;
	  PluginData  :pointer;
	  hContact    :THANDLE;
  end;
  POPUPDATACLASS = TPOPUPDATACLASS;

const
// wParam = 0
// lParam = (POPUPDATACLASS *)&pdc
  MS_POPUP_ADDPOPUPCLASS = 'Popup/AddPopupClass';

(* OLD
{
  Each skinned popup (e.g. with colorBack == POPUP_USE_SKINNED_BG) should have
  class set. Then you can choose separate skin for each class (for example, you
  can create separate class for your plugin and use it for all ypu popups. User
  would became able to choose skin for your popups independently from others)

  You have to register popup class before using it. To do so call
  "Popup/AddClass" with lParam = (LPARAM)(const AnsiChar * )popUpClassName.

  All class names are translated (via Translate()) before being added to list.
  You should use english names for them.

  There are three predefined classes and one for backward compatability.

  Note that you can add clases after popup wal loaded, e.g. you shoul intercept
  ME_SYSTEM_MODULESLOADED event
}
  MS_POPUP_ADDCLASS = 'Popup/AddClass';

  POPUP_CLASS_DEFAULT = 'Default';
  POPUP_CLASS_WARNING = 'Warning';
  POPUP_CLASS_NOTIFY  = 'Notify';
  POPUP_CLASS_OLDAPI  = 'Popup 1.0.1.x compatability'; // for internal purposes

const
  NFOPT_POPUP2_BACKCOLOR    = 'Popup2/BackColor';
  NFOPT_POPUP2_TEXTCOLOR    = 'Popup2/TextColor';
  NFOPT_POPUP2_TIMEOUT      = 'Popup2/Timeout';
  NFOPT_POPUP2_LCLICKSVC    = 'Popup2/LClickSvc';
  NFOPT_POPUP2_LCLICKCOOKIE = 'Popup2/LClickCookie';
  NFOPT_POPUP2_RCLICKSVC    = 'Popup2/RClickSvc';
  NFOPT_POPUP2_RCLICKCOOKIE = 'Popup2/RClickCookie';
  NFOPT_POPUP2_STATUSMODE   = 'Popup2/StatusMode';
  NFOPT_POPUP2_PLUGINDATA   = 'Popup2/PluginData';
  NFOPT_POPUP2_WNDPROC      = 'Popup2/WndProc';

  NFOPT_POPUP2_BACKCOLOR_S  = 'Popup2/BackColor/Save';
  NFOPT_POPUP2_TEXTCOLOR_S  = 'Popup2/TextColor/Save';
  NFOPT_POPUP2_TIMEOUT_S    = 'Popup2/Timeout/Save';

  MS_POPUP2_SHOW   = 'Popup2/Show';
  MS_POPUP2_UPDATE = 'Popup2/Update';
  MS_POPUP2_REMOVE = 'Popup2/Remove';
*)
///////////////////////////////////////////////////////////////
// Few notes about new popup api
// ------------------------------
// When you call any ADD service, Popup Plus creates local
// copy of POPUPDATA2 to store the data. Each time you call
// CHANGE service this data is updated. You can use the
// MS_POPUP_GETDATA2 service to retrieve Popups's copy of
// this data, however you MUST NOT chahge that.

// unicode or ansi mode
const
  PU2_ANSI         = 00;
  PU2_UNICODE      = 01;
  PU2_CUSTOM_POPUP = 02;

type
  PPOPUPDATA2 = ^TPOPUPDATA2;
  TPOPUPDATA2 = record
  // general
    cbSize:int;
    flags:dword;

  // miranda bindings
    lchContact:THANDLE;
    lchEvent  :THANDLE;

  // style
    colorBack:TCOLORREF;
    colorText:TCOLORREF;
    lchIcon:HICON;
    hbmAvatar:HBITMAP;
    pzTitle:TCHAR;
    pzText:TCHAR;
    lpzSkin:PAnsiChar;

  // time and timeout
    iSeconds:int;
    dwTimestamp:dword;

  // plugin bindings
    PluginWindowProc:TWNDPROC;
    PluginData:pointer;

  // popup actions
    actionCount:int;
    lpActions:PPOPUPACTION; // Ansi or unicode
    lchNotification:THANDLE;
  end;

const
// Creates new popup
//    wParam = (WPARAM)(LPPOPUPDATA2)&ppd2
//    lParam = (LPARAM)(combination of APF_* flags)
//    returns: window handle (if requested) of NULL on success, -1 on failure.
  MS_POPUP_ADDPOPUP2:PAnsiChar = 'Popup/AddPopup2';

// Update an popup
//    wParam = (WPARAM)(HWND)hwndPopup
//    lParam = (LPARAM)(LPPOPUPDATA2)&ppd2
//    returns: zero on success, -1 on failure.
  MS_POPUP_CHANGEPOPUP2:PAnsiChar = 'Popup/ChangePopup2';

{$ENDIF}