1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.IO;
9
10 namespace System.Windows.API
11 {
12 public const long ERROR_DUPLICATE_CODE_MAPPING = -2;
13 public const long ERROR_CODE_NOT_FOUND = -1;
14 public const long ERROR_OUT_OF_RESOURCES = 0;
15 public const long ERROR_FILE_NOT_FOUND = 1;
16 public const long ERROR_PATH_NOT_FOUND = 2;
17 public const long ERROR_BAD_FORMAT = 3;
18 public const long SE_ERR_ACCESSDENIED = 4;
19 public const long SE_ERR_ASSOCINCOMPLETE = 5;
20 public const long SE_ERR_DDEBUSY = 6;
21 public const long SE_ERR_DDEFAIL = 7;
22 public const long SE_ERR_DDETIMEOUT = 8;
23 public const long SE_ERR_DLLNOTFOUND = 9;
24 public const long SE_ERR_FNF = 10;
25 public const long SE_ERR_NOASSOC = 11;
26 public const long SE_ERR_OOM = 12;
27 public const long SE_ERR_PNF = 13;
28 public const long SE_ERR_SHARE = 14;
29
30 public string GetWindowsAPIErrorMessage(ulong errorCode)
31 {
32 wchar[4096] buffer;
33 WinFormatMessage(errorCode, &buffer[0]);
34 return ToUtf8(wstring(&buffer[0]));
35 }
36
37 public class WindowsAPIException : Exception
38 {
39 public WindowsAPIException(ulong errorCode_) : base(GetWindowsAPIErrorMessage(errorCode_)), errorCode(errorCode_)
40 {
41 }
42 public ulong ErrorCode() const
43 {
44 return errorCode;
45 }
46 private ulong errorCode;
47 }
48
49 public class CommonDialogError : Exception
50 {
51 public CommonDialogError(uint errorCode, const string& errorStr) : base("Common dialog error " + ToString(errorCode) + ": " + errorStr)
52 {
53 }
54 private uint errorCode;
55 }
56
57 public void* FindFirstChangeNotification(const string& directoryPath)
58 {
59 void* notificationHandle = WinFindFirstChangeNotification(directoryPath.Chars());
60 if (notificationHandle == null)
61 {
62 throw WindowsAPIException(WinGetLastError());
63 }
64 return notificationHandle;
65 }
66
67 public void FindNextChangeNotification(void* notificationHandle)
68 {
69 bool result = WinFindNextChangeNotification(notificationHandle);
70 if (!result)
71 {
72 throw WindowsAPIException(WinGetLastError());
73 }
74 }
75
76 public void FindCloseChangeNotification(void* notificationHandle)
77 {
78 bool result = WinFindCloseChangeNotification(notificationHandle);
79 if (!result)
80 {
81 throw WindowsAPIException(WinGetLastError());
82 }
83 }
84
85 public void* CreateEvent()
86 {
87 void* eventHandle = WinCreateEvent();
88 if (eventHandle == null)
89 {
90 throw WindowsAPIException(WinGetLastError());
91 }
92 return eventHandle;
93 }
94
95 public void SetEvent(void* eventHandle)
96 {
97 bool result = WinSetEvent(eventHandle);
98 if (!result)
99 {
100 throw WindowsAPIException(WinGetLastError());
101 }
102 }
103
104 public void ResetEvent(void* eventHandle)
105 {
106 bool result = WinResetEvent(eventHandle);
107 if (!result)
108 {
109 throw WindowsAPIException(WinGetLastError());
110 }
111 }
112
113 public void WaitEvent(void* eventHandle)
114 {
115 bool result = WinWaitEvent(eventHandle);
116 if (!result)
117 {
118 throw WindowsAPIException(WinGetLastError());
119 }
120 }
121
122 public void CloseHandle(void* handle)
123 {
124 bool result = WinCloseHandle(handle);
125 if (!result)
126 {
127 throw WindowsAPIException(WinGetLastError());
128 }
129 }
130
131 public void CloseEvent(void* eventHandle)
132 {
133 CloseHandle(eventHandle);
134 }
135
136 public int WaitForMultipleObjects(const List<void*>& handles)
137 {
138 int result = WinWaitForMultipleObjects(cast<uint>(handles.Count()), handles.Begin().Ptr());
139 if (result >= 0 && result <= handles.Count())
140 {
141 return result;
142 }
143 else
144 {
145 throw WindowsAPIException(WinGetLastError());
146 }
147 }
148
149 public void ShellExecute(const string& filePath)
150 {
151 long errorCode = 0;
152 bool succeeded = WinShellExecute(filePath.Chars(), errorCode);
153 if (!succeeded)
154 {
155 string errorMessage = "shell execution error for file '" + filePath + "': ";
156 string error = "out of resources";
157 switch (errorCode)
158 {
159 case ERROR_DUPLICATE_CODE_MAPPING:
160 {
161 error = "duplicate code mapping detected"; break;
162 }
163 case ERROR_CODE_NOT_FOUND:
164 {
165 error = "code not found"; break;
166 }
167 case ERROR_OUT_OF_RESOURCES:
168 {
169 error = "out of resources"; break;
170 }
171 case ERROR_FILE_NOT_FOUND:
172 {
173 error = "file not found"; break;
174 }
175 case ERROR_PATH_NOT_FOUND:
176 {
177 error = "path not found"; break;
178 }
179 case ERROR_BAD_FORMAT:
180 {
181 error = "invalid executable"; break;
182 }
183 case SE_ERR_ACCESSDENIED:
184 {
185 error = "access denied"; break;
186 }
187 case SE_ERR_ASSOCINCOMPLETE:
188 {
189 error = "invalid file association"; break;
190 }
191 case SE_ERR_DDEBUSY:
192 {
193 error = "DDE busy"; break;
194 }
195 case SE_ERR_DDEFAIL:
196 {
197 error = "DDE failed"; break;
198 }
199 case SE_ERR_DDETIMEOUT:
200 {
201 error = "DDE timeout"; break;
202 }
203 case SE_ERR_DLLNOTFOUND:
204 {
205 error = "DLL not found"; break;
206 }
207 case SE_ERR_FNF:
208 {
209 error = "file not found"; break;
210 }
211 case SE_ERR_NOASSOC:
212 {
213 error = "no association for this type of file"; break;
214 }
215 case SE_ERR_OOM:
216 {
217 error = "not enough memory"; break;
218 }
219 case SE_ERR_PNF:
220 {
221 error = "path not found"; break;
222 }
223 case SE_ERR_SHARE:
224 {
225 error = "sharing violation"; break;
226 }
227 }
228 errorMessage.Append(error);
229 throw Exception(errorMessage);
230 }
231 }
232
233 public ushort RegisterWindowClass(const char* windowClassName, uint style, int backgroundColor)
234 {
235 ushort windowClass = WinRegisterWindowClass(windowClassName, style, backgroundColor);
236 if (windowClass == 0u)
237 {
238 throw WindowsAPIException(WinGetLastError());
239 }
240 return windowClass;
241 }
242
243 public void* CreateWindowByClassAtom(ushort windowClass, const char* windowName, long style, long exStyle, Point location, Size size, Control* parent)
244 {
245 void* parentHandle = null;
246 if (parent != null)
247 {
248 parentHandle = parent->Handle();
249 }
250 void* result = WinCreateWindowByClassAtom(windowClass, windowName, style, exStyle, location.x, location.y, size.w, size.h, parentHandle);
251 if (result == null)
252 {
253 throw WindowsAPIException(WinGetLastError());
254 }
255 else
256 {
257 return result;
258 }
259 }
260
261 public void* CreateWindowByClassName(const char* windowClass, const char* windowName, long style, long exStyle, Point location, Size size, Control* parent)
262 {
263 void* parentHandle = null;
264 if (parent != null)
265 {
266 parentHandle = parent->Handle();
267 }
268 void* result = WinCreateWindowByClassName(windowClass, windowName, style, exStyle, location.x, location.y, size.w, size.h, parentHandle);
269 if (result == null)
270 {
271 throw WindowsAPIException(WinGetLastError());
272 }
273 else
274 {
275 return result;
276 }
277 }
278
279 public void MoveWindow(void* windowHandle, const Point& location, const Size& size, bool repaint)
280 {
281 bool succeeded = WinMoveWindow(windowHandle, location.x, location.y, size.w, size.h, repaint);
282 if (!succeeded)
283 {
284 throw WindowsAPIException(WinGetLastError());
285 }
286 }
287
288 public WinRect GetClientRect(void* windowHandle)
289 {
290 WinRect rect;
291 bool succeeded = WinGetClientRect(windowHandle, &rect);
292 if (!succeeded)
293 {
294 throw WindowsAPIException(WinGetLastError());
295 }
296 return rect;
297 }
298
299 public WinRect GetWindowRect(void* windowHandle)
300 {
301 WinRect rect;
302 bool succeeded = WinGetWindowRect(windowHandle, &rect);
303 if (!succeeded)
304 {
305 throw WindowsAPIException(WinGetLastError());
306 }
307 return rect;
308 }
309
310 public Point ClientToScreen(void* windowHandle, const Point& point)
311 {
312 Point pt(point);
313 bool succeeded = WinClientToScreen(windowHandle, &pt);
314 if (!succeeded)
315 {
316 throw WindowsAPIException(WinGetLastError());
317 }
318 return pt;
319 }
320
321 public Point ScreenToClient(void* windowHandle, const Point& point)
322 {
323 Point pt(point);
324 bool succeeded = WinScreenToClient(windowHandle, &pt);
325 if (!succeeded)
326 {
327 throw WindowsAPIException(WinGetLastError());
328 }
329 return pt;
330 }
331
332 public nothrow bool PtInRect(const Point& point, const WinRect& rect)
333 {
334 return WinPtInRect(&rect, &point);
335 }
336
337 public void SetWindowText(void* windowHandle, const string& text)
338 {
339 bool succeeded = WinSetWindowText(windowHandle, text.Chars());
340 if (!succeeded)
341 {
342 throw WindowsAPIException(WinGetLastError());
343 }
344 }
345
346 public int GetWindowTextLength(void* windowHandle)
347 {
348 int result = WinGetWindowTextLength(windowHandle);
349 if (result == 0)
350 {
351 ulong errorCode = WinGetLastError();
352 if (errorCode != 0u)
353 {
354 throw WindowsAPIException(errorCode);
355 }
356 }
357 return result;
358 }
359
360 public string GetWindowText(void* windowHandle)
361 {
362 int length = GetWindowTextLength(windowHandle);
363 UniquePtr<wchar> buffer(cast<wchar*>(MemAlloc(sizeof(wchar) * (length + 1))));
364 int result = WinGetWindowText(windowHandle, buffer.Get(), length + 1);
365 if (result == 0)
366 {
367 ulong errorCode = WinGetLastError();
368 if (errorCode != 0u)
369 {
370 throw WindowsAPIException(errorCode);
371 }
372 }
373 return ToUtf8(buffer.Get());
374 }
375
376 public void SetParentWindow(void* childWindowHandle, void* parentWindowHandle)
377 {
378 void* result = WinSetParent(childWindowHandle, parentWindowHandle);
379 if (result == null)
380 {
381 throw WindowsAPIException(WinGetLastError());
382 }
383 }
384
385 public void* BeginPaint(void* windowHandle, void*& paintStruct)
386 {
387 void* result = WinBeginPaint(windowHandle, paintStruct);
388 if (result == null)
389 {
390 throw WindowsAPIException(WinGetLastError());
391 }
392 return result;
393 }
394
395 public void EndPaint(void* windowHandle, void* paintStruct)
396 {
397 WinEndPaint(windowHandle, paintStruct);
398 }
399
400 public void InvalidateRect(void* windowHandle, WinRect* rect, bool eraseBackground)
401 {
402 bool succeeded = WinInvalidateRect(windowHandle, rect, eraseBackground);
403 if (!succeeded)
404 {
405 throw WindowsAPIException(WinGetLastError());
406 }
407 }
408
409 public nothrow bool MessageBeep(uint beepType)
410 {
411 return WinMessageBeep(beepType);
412 }
413
414 public void MessageBeepChecked(uint beepType)
415 {
416 bool succeeded = WinMessageBeep(beepType);
417 if (!succeeded)
418 {
419 throw WindowsAPIException(WinGetLastError());
420 }
421 }
422
423 public void* GetDC(void* windowHandle)
424 {
425 return WinGetDC(windowHandle);
426 }
427
428 public void PostMessage(void* windowHandle, uint msg, uint wparam, long lparam)
429 {
430 bool succeeded = WinPostMessage(windowHandle, msg, wparam, lparam);
431 if (!succeeded)
432 {
433 throw WindowsAPIException(WinGetLastError());
434 }
435 }
436
437 public void ThrowCommonDialogError(uint errorCode)
438 {
439 string errorStr;
440 switch (errorCode)
441 {
442 case 0xFFFFu:
443 {
444 errorStr = "CDERR_DIALOGFAILURE";
445 break;
446 }
447 case 0x0006u:
448 {
449 errorStr = "CDERR_FINDRESFAILURE";
450 break;
451 }
452 case 0x0002u:
453 {
454 errorStr = "CDERR_INITIALIZATION";
455 break;
456 }
457 case 0x0007u:
458 {
459 errorStr = "CDERR_LOADRESFAILURE";
460 break;
461 }
462 case 0x0005u:
463 {
464 errorStr = "CDERR_LOADSTRFAILURE";
465 break;
466 }
467 case 0x0008u:
468 {
469 errorStr = "CDERR_LOCKRESFAILURE";
470 break;
471 }
472 case 0x0009u:
473 {
474 errorStr = "CDERR_MEMALLOCFAILURE";
475 break;
476 }
477 case 0x000Au:
478 {
479 errorStr = "CDERR_MEMLOCKFAILURE";
480 break;
481 }
482 case 0x0004u:
483 {
484 errorStr = "CDERR_NOHINSTANCE";
485 break;
486 }
487 case 0x000Bu:
488 {
489 errorStr = "CDERR_NOHOOK";
490 break;
491 }
492 case 0x0003u:
493 {
494 errorStr = "CDERR_NOTEMPLATE";
495 break;
496 }
497 case 0x000Cu:
498 {
499 errorStr = "CDERR_REGISTERMSGFAIL";
500 break;
501 }
502 case 0x0001u:
503 {
504 errorStr = "CDERR_STRUCTSIZE";
505 break;
506 }
507 case 0x100Au:
508 {
509 errorStr = "PDERR_CREATEICFAILURE";
510 break;
511 }
512 case 0x100Cu:
513 {
514 errorStr = "PDERR_DEFAULTDIFFERENT";
515 break;
516 }
517 case 0x1009u:
518 {
519 errorStr = "PDERR_DNDMMISMATCH";
520 break;
521 }
522 case 0x1005u:
523 {
524 errorStr = "PDERR_GETDEVMODEFAIL";
525 break;
526 }
527 case 0x1006u:
528 {
529 errorStr = "PDERR_INITFAILURE";
530 break;
531 }
532 case 0x1004u:
533 {
534 errorStr = "PDERR_LOADDRVFAILURE";
535 break;
536 }
537 case 0x1008u:
538 {
539 errorStr = "PDERR_NODEFAULTPRN";
540 break;
541 }
542 case 0x1007u:
543 {
544 errorStr = "PDERR_NODEVICES";
545 break;
546 }
547 case 0x1002u:
548 {
549 errorStr = "PDERR_PARSEFAILURE";
550 break;
551 }
552 case 0x100Bu:
553 {
554 errorStr = "PDERR_PRINTERNOTFOUND";
555 break;
556 }
557 case 0x1003u:
558 {
559 errorStr = "PDERR_RETDEFFAILURE";
560 break;
561 }
562 case 0x1001u:
563 {
564 errorStr = "PDERR_SETUPFAILURE";
565 break;
566 }
567 case 0x2002u:
568 {
569 errorStr = "CFERR_MAXLESSTHANMIN";
570 break;
571 }
572 case 0x2001u:
573 {
574 errorStr = "CFERR_NOFONTS";
575 break;
576 }
577 case 0x3003u:
578 {
579 errorStr = "FNERR_BUFFERTOOSMALL";
580 break;
581 }
582 case 0x3002u:
583 {
584 errorStr = "FNERR_INVALIDFILENAME";
585 break;
586 }
587 case 0x3001u:
588 {
589 errorStr = "FNERR_SUBCLASSFAILURE";
590 break;
591 }
592 case 0x4001u:
593 {
594 errorStr = "FRERR_BUFFERLENGTHZERO";
595 break;
596 }
597 default:
598 {
599 errorStr = "generic error";
600 break;
601 }
602 }
603 MessageBox.Show(errorStr);
604
605 }
606
607 public const uint OFN_READONLY = 0x00000001u;
608 public const uint OFN_OVERWRITEPROMPT = 0x00000002u;
609 public const uint OFN_HIDEREADONLY = 0x00000004u;
610 public const uint OFN_NOCHANGEDIR = 0x00000008u;
611 public const uint OFN_SHOWHELP = 0x00000010u;
612 public const uint OFN_ENABLEHOOK = 0x00000020u;
613 public const uint OFN_ENABLETEMPLATE = 0x00000040u;
614 public const uint OFN_ENABLETEMPLATEHANDLE = 0x00000080u;
615 public const uint OFN_NOVALIDATE = 0x00000100u;
616 public const uint OFN_ALLOWMULTISELECT = 0x00000200u;
617 public const uint OFN_EXTENSIONDIFFERENT = 0x00000400u;
618 public const uint OFN_PATHMUSTEXIST = 0x00000800u;
619 public const uint OFN_FILEMUSTEXIST = 0x00001000u;
620 public const uint OFN_CREATEPROMPT = 0x00002000u;
621 public const uint OFN_SHAREAWARE = 0x00004000u;
622 public const uint OFN_NOREADONLYRETURN = 0x00008000u;
623 public const uint OFN_NOTESTFILECREATE = 0x00010000u;
624 public const uint OFN_NONETWORKBUTTON = 0x00020000u;
625 public const uint OFN_NOLONGNAMES = 0x00040000u;
626 public const uint OFN_EXPLORER = 0x00080000u;
627 public const uint OFN_NODEREFERENCELINKS = 0x00100000u;
628 public const uint OFN_LONGNAMES = 0x00200000u;
629
630 public bool GetOpenFileName(void* windowHandle, const List<Pair<string, string>>& descriptionFilterPairs, const string& initialDirectory, const string& defaultFilePath,
631 const string& defaultExtension, uint flags, string& currentDirectory, List<string>& fileNames)
632 {
633 long filterBufferSize = 0;
634 for (const Pair<string, string>& descriptionFilterPair : descriptionFilterPairs)
635 {
636 wstring description = ToUtf16(descriptionFilterPair.first);
637 wstring filter = ToUtf16(descriptionFilterPair.second);
638 filterBufferSize = filterBufferSize + description.Length() + 1 + filter.Length() + 1;
639 }
640 filterBufferSize = filterBufferSize + 1 + 1;
641 UniquePtr<wchar> filterBuffer = cast<wchar*>(MemAlloc(sizeof(wchar) * filterBufferSize));
642 wchar* filterBufferPtr = filterBuffer.Get();
643 for (const Pair<string, string>& descriptionFilterPair : descriptionFilterPairs)
644 {
645 wstring description = ToUtf16(descriptionFilterPair.first);
646 long descLen = StrCopy(filterBufferPtr, description.Chars(), description.Length());
647 filterBufferPtr = filterBufferPtr + descLen + 1;
648 wstring filter = ToUtf16(descriptionFilterPair.second);
649 long filterLen = StrCopy(filterBufferPtr, filter.Chars(), filter.Length());
650 filterBufferPtr = filterBufferPtr + filterLen + 1;
651 }
652 *filterBufferPtr++ = '\0';
653 *filterBufferPtr++ = '\0';
654 long fileNameBufferSize = 16 * 1024;
655 UniquePtr<wchar> fileNameBuffer = cast<wchar*>(MemAlloc(sizeof(wchar) * fileNameBufferSize));
656 wstring defFilePath = ToUtf16(defaultFilePath);
657 if (defaultFilePath.IsEmpty())
658 {
659 *fileNameBuffer.Get() = '\0';
660 }
661 else
662 {
663 StrCopy(fileNameBuffer.Get(), defFilePath.Chars(), defFilePath.Length());
664 }
665 wstring initialDir = ToUtf16(initialDirectory);
666 wstring defExt = ToUtf16(defaultExtension);
667 bool success = WinGetOpenFileName(windowHandle, filterBuffer.Get(), initialDir.Chars(), fileNameBuffer.Get(), cast<uint>(fileNameBufferSize), flags, defExt.Chars());
668 if (success)
669 {
670 long firstPathLength = StrLen(fileNameBuffer.Get());
671 string firstPath = ToUtf8(wstring(fileNameBuffer.Get(), firstPathLength));
672 if ((flags & OFN_ALLOWMULTISELECT) == 0)
673 {
674 currentDirectory = Path.GetDirectoryName(firstPath);
675 fileNames.Add(Path.GetFileName(firstPath));
676 }
677 else
678 {
679 currentDirectory = firstPath;
680 long pathStart = firstPathLength + 1;
681 wchar* wpath = fileNameBuffer.Get() + pathStart;
682 while (*wpath != '\0')
683 {
684 long pathLength = StrLen(wpath);
685 string path = ToUtf8(wstring(wpath, pathLength));
686 fileNames.Add(path);
687 wpath = wpath + pathLength + 1;
688 }
689 }
690 return true;
691 }
692 else
693 {
694 uint errorCode = WinCommDlgExtendedError();
695 if (errorCode == 0u)
696 {
697 return false;
698 }
699 else
700 {
701 ThrowCommonDialogError(errorCode);
702 }
703 }
704 return false;
705 }
706
707 public bool GetSaveFileName(void* windowHandle, const List<Pair<string, string>>& descriptionFilterPairs, const string& initialDirectory, const string& defaultFilePath,
708 const string& defaultExtension, uint flags, string& currentDirectory, string& filePath)
709 {
710 long filterBufferSize = 0;
711 for (const Pair<string, string>& descriptionFilterPair : descriptionFilterPairs)
712 {
713 wstring description = ToUtf16(descriptionFilterPair.first);
714 wstring filter = ToUtf16(descriptionFilterPair.second);
715 filterBufferSize = filterBufferSize + description.Length() + 1 + filter.Length() + 1;
716 }
717 filterBufferSize = filterBufferSize + 1 + 1;
718 UniquePtr<wchar> filterBuffer = cast<wchar*>(MemAlloc(sizeof(wchar) * filterBufferSize));
719 wchar* filterBufferPtr = filterBuffer.Get();
720 for (const Pair<string, string>& descriptionFilterPair : descriptionFilterPairs)
721 {
722 wstring description = ToUtf16(descriptionFilterPair.first);
723 long descLen = StrCopy(filterBufferPtr, description.Chars(), description.Length());
724 filterBufferPtr = filterBufferPtr + descLen + 1;
725 wstring filter = ToUtf16(descriptionFilterPair.second);
726 long filterLen = StrCopy(filterBufferPtr, filter.Chars(), filter.Length());
727 filterBufferPtr = filterBufferPtr + filterLen + 1;
728 }
729 *filterBufferPtr++ = '\0';
730 *filterBufferPtr++ = '\0';
731 long fileNameBufferSize = 1024;
732 UniquePtr<wchar> fileNameBuffer = cast<wchar*>(MemAlloc(sizeof(wchar) * fileNameBufferSize));
733 wstring defFilePath = ToUtf16(defaultFilePath);
734 if (defaultFilePath.IsEmpty())
735 {
736 *fileNameBuffer.Get() = '\0';
737 }
738 else
739 {
740 StrCopy(fileNameBuffer.Get(), defFilePath.Chars(), defFilePath.Length());
741 }
742 wstring initialDir = ToUtf16(initialDirectory);
743 wstring defExt = ToUtf16(defaultExtension);
744 bool success = WinGetSaveFileName(windowHandle, filterBuffer.Get(), initialDir.Chars(), fileNameBuffer.Get(), cast<uint>(fileNameBufferSize), flags, defExt.Chars());
745 if (success)
746 {
747 long firstPathLength = StrLen(fileNameBuffer.Get());
748 filePath = ToUtf8(wstring(fileNameBuffer.Get(), firstPathLength));
749 return true;
750 }
751 else
752 {
753 uint errorCode = WinCommDlgExtendedError();
754 if (errorCode == 0u)
755 {
756 return false;
757 }
758 else
759 {
760 ThrowCommonDialogError(errorCode);
761 }
762 }
763 return false;
764 }
765
766 public void* LoadImage(const char* name, uint type, int cx, int cy)
767 {
768 void* result = WinLoadImage(name, type, cx, cy);
769 if (result == null)
770 {
771 throw WindowsAPIException(WinGetLastError());
772 }
773 return result;
774 }
775
776 public void* LoadCursor(const char* name)
777 {
778 void* result = WinLoadCursor(name);
779 if (result == null)
780 {
781 throw WindowsAPIException(WinGetLastError());
782 }
783 return result;
784 }
785
786 public void* LoadIcon(const char* name)
787 {
788 void* result = WinLoadIcon(name);
789 if (result == null)
790 {
791 throw WindowsAPIException(WinGetLastError());
792 }
793 return result;
794 }
795
796 public void* LoadBitmap(const char* name)
797 {
798 void* result = WinLoadBitmap(name);
799 if (result == null)
800 {
801 throw WindowsAPIException(WinGetLastError());
802 }
803 return result;
804 }
805
806 public int GetSystemMetrics(int index)
807 {
808 int result = WinGetSystemMetrics(index);
809 if (result == 0)
810 {
811 throw WindowsAPIException(WinGetLastError());
812 }
813 return result;
814 }
815
816 public void* GetTopWindow(void* windowHandle)
817 {
818 return WinGetTopWindow(windowHandle);
819 }
820
821 public void BringWindowToTop(void* windowHandle)
822 {
823 bool succeeded = WinBringWindowToTop(windowHandle);
824 if (!succeeded)
825 {
826 throw WindowsAPIException(WinGetLastError());
827 }
828 }
829
830 public enum WindowPos : int
831 {
832 top = 0, bottom = 1, topmost = -1, noTopmost = -2
833 }
834
835 public nothrow void* WindowPosHandle(WindowPos pos)
836 {
837 return cast<void*>(cast<ulong>(cast<int>(pos)));
838 }
839
840 public enum SetWindowPosFlags : uint
841 {
842 SWP_ASYNCWINDOWPOS = 0x4000u,
843 SWP_DEFERERASE = 0x2000u,
844 SWP_DRAWFRAME = 0x20u,
845 SWP_FRAMECHANGED = 0x20u,
846 SWP_HIDEWINDOW = 0x80u,
847 SWP_NOACTIVATE = 0x10u,
848 SWP_NOCOPYBITS = 0x100u,
849 SWP_NOMOVE = 0x2u,
850 SWP_NOOWNERZORDER = 0x200u,
851 SWP_NOREDRAW = 0x8u,
852 SWP_NOREPOSITION = 0x200u,
853 SWP_NOSENDCHANGING = 0x400u,
854 SWP_NOSIZE = 0x1u,
855 SWP_NOZORDER = 0x4u,
856 SWP_SHOWWINDOW = 0x40u
857 }
858
859 public void SetWindowPos(void* windowHandle, void* insertAfterWindowHandle, int x, int y, int cx, int cy, SetWindowPosFlags flags)
860 {
861 bool succeeded = WinSetWindowPos(windowHandle, insertAfterWindowHandle, x, y, cx, cy, cast<uint>(flags));
862 if (!succeeded)
863 {
864 throw WindowsAPIException(WinGetLastError());
865 }
866 }
867
868 public enum ClassLongIndex : int
869 {
870 GCL_CBCLSEXTRA = -20,
871 GCL_CBWNDEXTRA = -18,
872 GCL_HBRBACKGROUND = -10,
873 GCL_HCURSOR = -12,
874 GCL_HICON = -14,
875 GCL_HICONSM = -34,
876 GCL_HMODULE = -16,
877 GCL_MENUNAME = -8,
878 GCL_STYLE = -26,
879 GCL_WNDPROC = -24
880 }
881
882 public long GetClassLong(void* windowHandle, ClassLongIndex index)
883 {
884 long value = WinGetClassLong(windowHandle, cast<int>(index));
885 if (value == 0)
886 {
887 ulong errorCode = WinGetLastError();
888 if (errorCode != 0u)
889 {
890 throw WindowsAPIException(errorCode);
891 }
892 }
893 return value;
894 }
895
896 public void SetClassLong(void* windowHandle, ClassLongIndex index, long newValue)
897 {
898 long value = WinSetClassLong(windowHandle, cast<int>(index), newValue);
899 if (value == 0)
900 {
901 ulong errorCode = WinGetLastError();
902 if (errorCode != 0u)
903 {
904 throw WindowsAPIException(errorCode);
905 }
906 }
907 }
908
909 public enum WindowLongIndex : int
910 {
911 GWL_EXSTYLE = -20,
912 GWLP_HINSTANCE = -6,
913 GWLP_ID = -12,
914 GWL_STYLE = -16,
915 GWLP_USERDATA = -21,
916 GWLP_WNDPROC = -4
917 }
918
919 public long GetWindowLong(void* windowHandle, WindowLongIndex index)
920 {
921 long value = WinGetWindowLong(windowHandle, cast<int>(index));
922 if (value == 0)
923 {
924 throw WindowsAPIException(WinGetLastError());
925 }
926 return value;
927 }
928
929 public void SetWindowLong(void* windowHandle, WindowLongIndex index, long newValue)
930 {
931 bool succeeded = WinSetWindowLong(windowHandle, cast<int>(index), newValue);
932 if (!succeeded)
933 {
934 throw WindowsAPIException(WinGetLastError());
935 }
936 }
937
938 public void ScrollWindow(void* windowHandle, int xAmount, int yAmount, const Rect* clientRect, const Rect* clipRect)
939 {
940 int clientLocX = 0;
941 int clientLocY = 0;
942 int clientSizeW = 0;
943 int clientSizeH = 0;
944 if (clientRect != null)
945 {
946 clientLocX = clientRect->location.x;
947 clientLocY = clientRect->location.y;
948 clientSizeW = clientRect->size.w;
949 clientSizeH = clientRect->size.h;
950 }
951 int clipLocX = 0;
952 int clipLocY = 0;
953 int clipSizeW = 0;
954 int clipSizeH = 0;
955 if (clipRect != null)
956 {
957 clipLocX = clipRect->location.x;
958 clipLocY = clipRect->location.y;
959 clipSizeW = clipRect->size.w;
960 clipSizeH = clipRect->size.h;
961 }
962 bool succeeded = WinScrollWindow(windowHandle, xAmount, yAmount, clientLocX, clientLocY, clientSizeW, clientSizeH, clipLocX, clipLocY, clipSizeW, clipSizeH);
963 if (!succeeded)
964 {
965 throw WindowsAPIException(WinGetLastError());
966 }
967 }
968
969 public void ScrollWindowEx(void* windowHandle, int dx, int dy, const Rect* clientRect, const Rect* clipRect, const Rect& updateRect)
970 {
971 int clientLocX = 0;
972 int clientLocY = 0;
973 int clientSizeW = 0;
974 int clientSizeH = 0;
975 if (clientRect != null)
976 {
977 clientLocX = clientRect->location.x;
978 clientLocY = clientRect->location.y;
979 clientSizeW = clientRect->size.w;
980 clientSizeH = clientRect->size.h;
981 }
982 int clipLocX = 0;
983 int clipLocY = 0;
984 int clipSizeW = 0;
985 int clipSizeH = 0;
986 if (clipRect != null)
987 {
988 clipLocX = clipRect->location.x;
989 clipLocY = clipRect->location.y;
990 clipSizeW = clipRect->size.w;
991 clipSizeH = clipRect->size.h;
992 }
993 int x1 = updateRect.location.x;
994 int y1 = updateRect.location.y;
995 int x2 = updateRect.location.x + updateRect.size.w;
996 int y2 = updateRect.location.y + updateRect.size.h;
997 bool succeeded = WinScrollWindowEx(windowHandle, dx, dy, clientLocX, clientLocY, clientSizeW, clientSizeH, clipLocX, clipLocY, clipSizeW, clipSizeH, x1, y1, x2, y2);
998 if (!succeeded)
999 {
1000 throw WindowsAPIException(WinGetLastError());
1001 }
1002 }
1003
1004 public enum ScrollBar : int
1005 {
1006 SB_BOTH = 3,
1007 SB_CTL = 2,
1008 SB_HORZ = 0,
1009 SB_VERT = 1
1010 }
1011
1012 public void GetScrollInfo(void* windowHandle, ScrollBar scrollBar, uint& nPage, int& nPos, int& nMin, int& nMax, int& nTrackPos)
1013 {
1014 bool succeeded = WinGetScrollInfo(windowHandle, cast<int>(scrollBar), nPage, nPos, nMin, nMax, nTrackPos);
1015 if (!succeeded)
1016 {
1017 throw WindowsAPIException(WinGetLastError());
1018 }
1019 }
1020
1021 public enum ScrollInfoMask : uint
1022 {
1023 SIF_DISABLENOSCROLL = 8u,
1024 SIF_PAGE = 2u,
1025 SIF_POS = 4u,
1026 SIF_RANGE = 1u
1027 }
1028
1029 public int SetScrollInfo(void* windowHandle, ScrollBar scrollBar, ScrollInfoMask mask, bool redraw, uint nPage, int nPos, int nMin, int nMax)
1030 {
1031 return WinSetScrollInfo(windowHandle, cast<int>(scrollBar), cast<uint>(mask), redraw, nPage, nPos, nMin, nMax);
1032 }
1033
1034 public void ShowScrollBar(void* windowHandle, ScrollBar scrollBar, bool show)
1035 {
1036 bool succeeded = WinShowScrollBar(windowHandle, cast<int>(scrollBar), show);
1037 if (!succeeded)
1038 {
1039 throw WindowsAPIException(WinGetLastError());
1040 }
1041 }
1042
1043 public void CreateCaret(void* windowHandle, void* bitmapHandle, int width, int height)
1044 {
1045 bool succeeded = WinCreateCaret(windowHandle, bitmapHandle, width, height);
1046 if (!succeeded)
1047 {
1048 throw WindowsAPIException(WinGetLastError());
1049 }
1050 }
1051
1052 public void DestroyCaret()
1053 {
1054 bool succeeded = WinDestroyCaret();
1055 if (!succeeded)
1056 {
1057 throw WindowsAPIException(WinGetLastError());
1058 }
1059 }
1060
1061 public void ShowCaret(void* windowHandle)
1062 {
1063 bool succeeded = WinShowCaret(windowHandle);
1064 if (!succeeded)
1065 {
1066 throw WindowsAPIException(WinGetLastError());
1067 }
1068 }
1069
1070 public void HideCaret(void* windowHandle)
1071 {
1072 bool succeeded = WinHideCaret(windowHandle);
1073 if (!succeeded)
1074 {
1075 throw WindowsAPIException(WinGetLastError());
1076 }
1077 }
1078
1079 public Point GetCaretPos()
1080 {
1081 Point caretPos;
1082 bool succeeded = WinGetCaretPos(caretPos.x, caretPos.y);
1083 if (!succeeded)
1084 {
1085 throw WindowsAPIException(WinGetLastError());
1086 }
1087 return caretPos;
1088 }
1089
1090 public void SetCaretPos(const Point& caretPos)
1091 {
1092 bool succeeded = WinSetCaretPos(caretPos.x, caretPos.y);
1093 if (!succeeded)
1094 {
1095 throw WindowsAPIException(WinGetLastError());
1096 }
1097 }
1098
1099 public void SetTimer(void* windowHandle, uint timerId, uint elapseMs)
1100 {
1101 bool succeeded = WinSetTimer(windowHandle, timerId, elapseMs);
1102 if (!succeeded)
1103 {
1104 throw WindowsAPIException(WinGetLastError());
1105 }
1106 }
1107
1108 public void KillTimer(void* windowHandle, uint timerId)
1109 {
1110 bool succeeded = WinKillTimer(windowHandle, timerId);
1111 if (!succeeded)
1112 {
1113 throw WindowsAPIException(WinGetLastError());
1114 }
1115 }
1116
1117 public uint RegisterClipboardFormat(const char* formatName)
1118 {
1119 uint format = WinRegisterClipboardFormat(formatName);
1120 if (format == 0u)
1121 {
1122 throw WindowsAPIException(WinGetLastError());
1123 }
1124 return format;
1125 }
1126
1127 public void OpenClipboard(void* windowHandle)
1128 {
1129 int maxWait = 100;
1130 for (int i = 0; i < 5; ++i;)
1131 {
1132 bool succeeded = WinOpenClipboard(windowHandle);
1133 if (succeeded)
1134 {
1135 return;
1136 }
1137 else if (i < 4)
1138 {
1139 Sleep(Duration.FromMilliseconds(Random() % maxWait));
1140 maxWait = maxWait * 2;
1141 }
1142 }
1143 throw WindowsAPIException(WinGetLastError());
1144 }
1145
1146 public void CloseClipboard()
1147 {
1148 bool succeeded = WinCloseClipboard();
1149 if (!succeeded)
1150 {
1151 throw WindowsAPIException(WinGetLastError());
1152 }
1153 }
1154
1155 public void EmptyClipboard()
1156 {
1157 bool succeeded = WinEmptyClipboard();
1158 if (!succeeded)
1159 {
1160 throw WindowsAPIException(WinGetLastError());
1161 }
1162 }
1163
1164 public void* SetClipboardData(uint format, void* mem)
1165 {
1166 void* retval = WinSetClipboardData(format, mem);
1167 if (retval == null)
1168 {
1169 throw WindowsAPIException(WinGetLastError());
1170 }
1171 return retval;
1172 }
1173
1174 public void* GetClipboardData(uint format)
1175 {
1176 void* retval = WinGetClipboardData(format);
1177 if (retval == null)
1178 {
1179 throw WindowsAPIException(WinGetLastError());
1180 }
1181 return retval;
1182 }
1183
1184 public bool IsClipboardFormatAvailable(uint format)
1185 {
1186 return WinIsClipboardFormatAvailable(format);
1187 }
1188
1189 public void AddClipboardFormatListener(void* windowHandle)
1190 {
1191 bool succeeded = WinAddClipboardFormatListener(windowHandle);
1192 if (!succeeded)
1193 {
1194 throw WindowsAPIException(WinGetLastError());
1195 }
1196 }
1197
1198 public void RemoveClipboardFormatListener(void* windowHandle)
1199 {
1200 bool succeeded = WinRemoveClipboardFormatListener(windowHandle);
1201 if (!succeeded)
1202 {
1203 throw WindowsAPIException(WinGetLastError());
1204 }
1205 }
1206
1207 public enum GlobalAllocFlags : uint
1208 {
1209 GMEM_FIXED = 0x0u,
1210 GHND = 0x0042u,
1211 GMEM_MOVEABLE = 0x0002u,
1212 GMEM_ZEROINIT = 0x0040u,
1213 GPTR = 0x0040u
1214 }
1215
1216 public void* GlobalAlloc(GlobalAllocFlags flags, ulong size)
1217 {
1218 void* retval = WinGlobalAlloc(cast<uint>(flags), size);
1219 if (retval == null)
1220 {
1221 throw WindowsAPIException(WinGetLastError());
1222 }
1223 return retval;
1224 }
1225
1226 public void* GlobalLock(void* memHandle)
1227 {
1228 void* retval = WinGlobalLock(memHandle);
1229 if (retval == null)
1230 {
1231 throw WindowsAPIException(WinGetLastError());
1232 }
1233 return retval;
1234 }
1235
1236 public void GlobalUnlock(void* memHandle)
1237 {
1238 bool retval = WinGlobalUnlock(memHandle);
1239 if (!retval)
1240 {
1241 ulong error = WinGetLastError();
1242 if (error != 0u)
1243 {
1244 throw WindowsAPIException(error);
1245 }
1246 }
1247 }
1248
1249 public void GlobalFree(void* memHandle)
1250 {
1251 void* retval = WinGlobalFree(memHandle);
1252 if (retval != null)
1253 {
1254 throw WindowsAPIException(WinGetLastError());
1255 }
1256 }
1257
1258 public ulong GlobalSize(void* memHandle)
1259 {
1260 ulong size = WinGlobalSize(memHandle);
1261 if (size == 0u)
1262 {
1263 throw WindowsAPIException(WinGetLastError());
1264 }
1265 return size;
1266 }
1267
1268 public void GetCursorPos(int& x, int& y)
1269 {
1270 if (!WinGetCursorPos(x, y))
1271 {
1272 throw WindowsAPIException(WinGetLastError());
1273 }
1274 }
1275 public string GetFolder(void* windowHandle, const string& defaultDirectory)
1276 {
1277 wstring defaultDir = ToUtf16(defaultDirectory);
1278 long folderNameBufferSize = 1024;
1279 UniquePtr<wchar> folderNameBuffer = cast<wchar*>(MemAlloc(sizeof(wchar) * folderNameBufferSize));
1280 bool success = WinGetFolder(windowHandle, defaultDir.Chars(), folderNameBuffer.Get(), cast<uint>(folderNameBufferSize));
1281 if (success)
1282 {
1283 wstring folderName(folderNameBuffer.Get());
1284 return ToUtf8(folderName);
1285 }
1286 else
1287 {
1288 return string();
1289 }
1290 }
1291 }