1 /*
2  * PROJECT:         ReactOS Tests
3  * FILE:            rostests/win32/user32/psmtest/psmtest.c
4  * PURPOSE:         Side by side comparison of the undocumented
5  *                  LpkPSMTextOut and UserLpkPSMTextOut functions
6  *
7  * PROGRAMMER:      Program skeleton: https://github.com/TransmissionZero/MinGW-Win32-Application
8  *                  Test code by Baruch Rutman
9  */
10 
11 #include <windows.h>
12 #include <commctrl.h>
13 #include <strsafe.h>
14 
15 #define IDI_APPICON     101
16 #define IDR_ACCELERATOR 103
17 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
18 
19 /* Prototypes */
20 INT WINAPI LpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int cString, DWORD dwFlags);
21 INT WINAPI UserLpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int cString, DWORD dwFlags);
22 
23 /* Main window class and title */
24 static LPCWSTR MainWndClass = L"PSM Test";
25 
26 #define LPK 1
27 #define USERLPK 2
28 static void DrawTest(HDC hdc, int ypos, LPCWSTR str, DWORD dwFlags, int testtype)
29 {
30     WCHAR Result[100];
31     INT ret = 0;
32 
33     if (testtype == LPK)
34     {
35         ret = LpkPSMTextOut(hdc, 0, ypos, str, (!str) ? 10 : wcslen(str), dwFlags);
36         StringCchPrintfW(Result, 100, L"Return Value = %d", ret);
37         TextOutW(hdc, 200, ypos, Result, wcslen(Result));
38     }
39     else if (testtype == USERLPK)
40     {
41         ret = UserLpkPSMTextOut(hdc, 400, ypos, str, wcslen(str), dwFlags);
42         StringCchPrintfW(Result, 100, L"Return Value = %d", ret);
43         TextOutW(hdc, 600, ypos, Result, wcslen(Result));
44     }
45 
46 }
47 
48 /* Our application entry point */
49 int WINAPI
50 wWinMain(HINSTANCE hInstance,
51           HINSTANCE hPrevInstance,
52           LPTSTR lpszCmdLine,
53           int nCmdShow)
54 {
55   INITCOMMONCONTROLSEX icc;
56   HWND hWnd;
57   HACCEL hAccelerators;
58   MSG msg;
59   WNDCLASSEXW wc;
60 
61   /* Class for our main window */
62   wc.cbSize        = sizeof(wc);
63   wc.style         = 0;
64   wc.lpfnWndProc   = &MainWndProc;
65   wc.cbClsExtra    = 0;
66   wc.cbWndExtra    = 0;
67   wc.hInstance     = hInstance;
68   wc.hIcon         = (HICON)LoadImage(hInstance, MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE |
69                                       LR_DEFAULTCOLOR | LR_SHARED);
70   wc.hCursor       = (HCURSOR)LoadImageW(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
71   wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
72   wc.lpszClassName = MainWndClass;
73   wc.hIconSm       = (HICON)LoadImage(hInstance, MAKEINTRESOURCEW(IDI_APPICON), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
74 
75   /* Initialise common controls */
76   icc.dwSize = sizeof(icc);
77   icc.dwICC = ICC_WIN95_CLASSES;
78   InitCommonControlsEx(&icc);
79 
80   /* Register our main window class, or error */
81   if (!RegisterClassExW(&wc))
82   {
83     MessageBoxW(NULL, L"Error registering main window class.", L"Error", MB_ICONERROR | MB_OK);
84     return 0;
85   }
86 
87   hWnd = CreateWindowExW(0, MainWndClass, MainWndClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
88                              NULL, NULL, hInstance, NULL);
89 
90   /* Create our main window, or error */
91   if (!hWnd)
92   {
93     MessageBoxW(NULL, L"Error creating main window.", L"Error", MB_ICONERROR | MB_OK);
94     return 0;
95   }
96 
97   /* Load accelerators */
98   hAccelerators = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(IDR_ACCELERATOR));
99 
100   /* Show main window and force a paint */
101   ShowWindow(hWnd, nCmdShow | SW_MAXIMIZE);
102   UpdateWindow(hWnd);
103 
104   /* Main message loop */
105   while (GetMessageW(&msg, NULL, 0, 0) > 0)
106   {
107     if (!TranslateAcceleratorW(hWnd, hAccelerators, &msg))
108     {
109       TranslateMessage(&msg);
110       DispatchMessageW(&msg);
111     }
112   }
113 
114   return (int)msg.wParam;
115 }
116 
117 /* Window procedure for our main window */
118 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
119 {
120   switch (msg)
121   {
122 
123     case WM_GETMINMAXINFO:
124     {
125       /* Prevent our window from being sized too small */
126       MINMAXINFO *minMax = (MINMAXINFO*)lParam;
127       minMax->ptMinTrackSize.x = 220;
128       minMax->ptMinTrackSize.y = 110;
129 
130       return 0;
131     }
132 
133     case WM_PAINT:
134         {
135             PAINTSTRUCT ps;
136             HDC hdc = BeginPaint(hWnd, &ps);
137 
138             enum {
139                 ALEF = 0x5D0,
140                 BET,
141                 GIMEL,
142                 DALET,
143                 HEY,
144                 VAV,
145                 ZAYIN,
146                 HET,
147                 TET,
148                 YUD,
149                 KAF_SOFIT,
150                 KAF,
151                 LAMED,
152                 MEM_SOFIT,
153                 MEM,
154                 NUN_SOFIT,
155                 NUN,
156                 SAMEKH,
157                 AYIN,
158                 PEY_SOFIT,
159                 PEY,
160                 TSADI_SOFIT,
161                 TSADI,
162                 QOF,
163                 RESH,
164                 SHIN,
165                 TAV
166             };
167 
168             LOGFONTW font;
169             HFONT hfont;
170             WCHAR Test[] = L"&Test Text";
171             WCHAR Test2[] = L"&Test\nText";
172             WCHAR Test3[] = L"&Test\tText";
173             WCHAR Test4[] = L"&Test T&ex&t";
174             WCHAR Test5[] = { TET, QOF, SAMEKH, TET, L' ', L'&', BET, DALET, YUD, QOF, HEY, 0 };
175             WCHAR Test6[] = L"Test&&Text";
176             WCHAR Test7[] = { BET, DALET, YUD, QOF, HEY, L'&', 'T','e','s','t', 0};
177             WCHAR Test8[] = L"TestText&";
178             WCHAR Test9[] = L"TestText&&";
179             WCHAR Test10[] = L"TestText";
180 
181             ZeroMemory(&font, sizeof(LOGFONTW));
182             StringCchCopyW(font.lfFaceName, 32, L"Microsoft Sans Serif");
183             hfont = CreateFontIndirectW(&font);
184             SelectObject(hdc, hfont);
185             SetBkMode(hdc, TRANSPARENT);
186 
187             DrawTest(hdc, 0,   Test,  0, LPK);
188             DrawTest(hdc, 20,  Test,  DT_NOPREFIX, LPK);
189             DrawTest(hdc, 40,  Test,  DT_PREFIXONLY, LPK);
190             DrawTest(hdc, 60,  Test2, DT_SINGLELINE, LPK);
191             DrawTest(hdc, 80,  Test2, 0, LPK);
192             DrawTest(hdc, 100, Test2, DT_CALCRECT, LPK);
193             DrawTest(hdc, 120, Test3, 0, LPK);
194             DrawTest(hdc, 140, Test3, DT_EXPANDTABS, LPK);
195             DrawTest(hdc, 160, NULL,  0, LPK);
196             DrawTest(hdc, 180, Test4, 0, LPK);
197             DrawTest(hdc, 200, Test4, DT_NOPREFIX, LPK);
198             DrawTest(hdc, 220, Test4, DT_HIDEPREFIX, LPK);
199             DrawTest(hdc, 240, Test5, 0, LPK);
200             DrawTest(hdc, 260, Test5, DT_NOPREFIX, LPK);
201             DrawTest(hdc, 280, Test5, DT_HIDEPREFIX, LPK);
202             DrawTest(hdc, 300, Test5, DT_PREFIXONLY, LPK);
203             DrawTest(hdc, 320, Test6, 0, LPK);
204             DrawTest(hdc, 340, Test6, DT_NOPREFIX, LPK);
205             DrawTest(hdc, 360, Test6, DT_HIDEPREFIX, LPK);
206             DrawTest(hdc, 380, Test6, DT_PREFIXONLY, LPK);
207             DrawTest(hdc, 400, Test7, 0, LPK);
208             DrawTest(hdc, 420, Test7, DT_NOPREFIX, LPK);
209             DrawTest(hdc, 440, Test7, DT_HIDEPREFIX, LPK);
210             DrawTest(hdc, 460, Test7, DT_PREFIXONLY, LPK);
211             DrawTest(hdc, 480, Test7, DT_RTLREADING, LPK);
212             SetTextAlign(hdc, GetTextAlign(hdc) | TA_RTLREADING);
213             DrawTest(hdc, 500, Test7, 0, LPK);
214             SetTextAlign(hdc, GetTextAlign(hdc) & ~TA_RTLREADING);
215             DrawTest(hdc, 520, Test8, 0, LPK);
216             DrawTest(hdc, 540, Test8, DT_NOPREFIX, LPK);
217             DrawTest(hdc, 560, Test8, DT_HIDEPREFIX, LPK);
218             DrawTest(hdc, 580, Test8, DT_PREFIXONLY, LPK);
219             DrawTest(hdc, 600, Test9, 0, LPK);
220             DrawTest(hdc, 620, Test9, DT_NOPREFIX, LPK);
221             DrawTest(hdc, 640, Test9, DT_HIDEPREFIX, LPK);
222             DrawTest(hdc, 660, Test9, DT_PREFIXONLY, LPK);
223             DrawTest(hdc, 680, Test10, 0, LPK);
224             DrawTest(hdc, 700, Test10, DT_NOPREFIX, LPK);
225             DrawTest(hdc, 720, Test10, DT_HIDEPREFIX, LPK);
226             DrawTest(hdc, 740, Test10, DT_PREFIXONLY, LPK);
227 
228             TextOutW(hdc, 100, 760, L"LpkPSMTextOut", 13);
229 
230             DrawTest(hdc, 0,   Test,  0, USERLPK);
231             DrawTest(hdc, 20,  Test,  DT_NOPREFIX, USERLPK);
232             DrawTest(hdc, 40,  Test,  DT_PREFIXONLY, USERLPK);
233             DrawTest(hdc, 60,  Test2, DT_SINGLELINE, USERLPK);
234             DrawTest(hdc, 80,  Test2, 0, USERLPK);
235             DrawTest(hdc, 100, Test2, DT_CALCRECT, USERLPK);
236             DrawTest(hdc, 120, Test3, 0, USERLPK);
237             DrawTest(hdc, 140, Test3, DT_EXPANDTABS, USERLPK);
238             /* DrawTest(hdc, 160, NULL, 0, USERLPK); */ /* Crash on windows */
239             DrawTest(hdc, 180, Test4, 0, USERLPK);
240             DrawTest(hdc, 200, Test4, DT_NOPREFIX, USERLPK);
241             DrawTest(hdc, 220, Test4, DT_HIDEPREFIX, USERLPK);
242             DrawTest(hdc, 240, Test5, 0, USERLPK);
243             DrawTest(hdc, 260, Test5, DT_NOPREFIX, USERLPK);
244             DrawTest(hdc, 280, Test5, DT_HIDEPREFIX, USERLPK);
245             DrawTest(hdc, 300, Test5, DT_PREFIXONLY, USERLPK);
246             DrawTest(hdc, 320, Test6, 0, USERLPK);
247             DrawTest(hdc, 340, Test6, DT_NOPREFIX, USERLPK);
248             DrawTest(hdc, 360, Test6, DT_HIDEPREFIX, USERLPK);
249             DrawTest(hdc, 380, Test6, DT_PREFIXONLY, USERLPK);
250             DrawTest(hdc, 400, Test7, 0, USERLPK);
251             DrawTest(hdc, 420, Test7, DT_NOPREFIX, USERLPK);
252             DrawTest(hdc, 440, Test7, DT_HIDEPREFIX, USERLPK);
253             DrawTest(hdc, 460, Test7, DT_PREFIXONLY, USERLPK);
254             DrawTest(hdc, 480, Test7, DT_RTLREADING, USERLPK);
255             SetTextAlign(hdc, GetTextAlign(hdc) | TA_RTLREADING);
256             DrawTest(hdc, 500, Test7, 0, USERLPK);
257             SetTextAlign(hdc, GetTextAlign(hdc) & ~TA_RTLREADING);
258             DrawTest(hdc, 520, Test8, 0, USERLPK);
259             DrawTest(hdc, 540, Test8, DT_NOPREFIX, USERLPK);
260             DrawTest(hdc, 560, Test8, DT_HIDEPREFIX, USERLPK);
261             DrawTest(hdc, 580, Test8, DT_PREFIXONLY, USERLPK);
262             DrawTest(hdc, 600, Test9, 0, USERLPK);
263             DrawTest(hdc, 620, Test9, DT_NOPREFIX, USERLPK);
264             DrawTest(hdc, 640, Test9, DT_HIDEPREFIX, USERLPK);
265             DrawTest(hdc, 660, Test9, DT_PREFIXONLY, USERLPK);
266             DrawTest(hdc, 680, Test10, 0, USERLPK);
267             DrawTest(hdc, 700, Test10, DT_NOPREFIX, USERLPK);
268             DrawTest(hdc, 720, Test10, DT_HIDEPREFIX, USERLPK);
269             DrawTest(hdc, 740, Test10, DT_PREFIXONLY, USERLPK);
270 
271             TextOutW(hdc, 500, 760, L"UserLpkPSMTextOut", 17);
272 
273             EndPaint(hWnd, &ps);
274             break;
275         }
276 
277     case WM_DESTROY:
278     {
279       PostQuitMessage(0);
280       return 0;
281     }
282   }
283   return DefWindowProcW(hWnd, msg, wParam, lParam);
284 }
285