ReactOS  0.4.14-dev-358-gbef841c
biditext.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Tests
3  * FILE: rostests/win32/user32/biditext/biditext.c
4  * PURPOSE: Demonstrates how ExtTextOut and GetCharacterPlacement
5  * handle bidirectional text strings via certain selection
6  * of flags provided to them.
7  *
8  * PROGRAMMER: Program skeleton: https://github.com/TransmissionZero/MinGW-Win32-Application
9  * Test code by Baruch Rutman
10  */
11 
12 #include "biditext.h"
13 
14 /* Prototypes */
15 DWORD WINAPI LpkGetCharacterPlacement(HDC hdc, LPCWSTR lpString, INT uCount, INT nMaxExtent,
16  GCP_RESULTSW *lpResults, DWORD dwFlags, DWORD dwUnused);
17 
18 BOOL WINAPI LpkExtTextOut(HDC hdc, int x, int y,
19  UINT fuOptions, const RECT *lprc, LPCWSTR lpString,
20  UINT uCount , const INT *lpDx, INT unknown);
21 
22 /* Global instance handle */
24 
25 /* Our application entry point */
26 int WINAPI
28  HINSTANCE hPrevInstance,
29  LPTSTR lpszCmdLine,
30  int nCmdShow)
31 {
33  HWND hWnd;
34  HACCEL hAccelerators;
35  MSG msg;
36 
37  /* Assign global HINSTANCE */
39 
40  /* Initialise common controls */
41  icc.dwSize = sizeof(icc);
44 
45  /* Register our main window class, or error */
47  {
48  MessageBox(NULL, TEXT("Error registering main window class."), TEXT("Error"), MB_ICONERROR | MB_OK);
49  return 0;
50  }
51 
52  /* Create our main window, or error */
53  if (!(hWnd = CreateMainWindow()))
54  {
55  MessageBox(NULL, TEXT("Error creating main window."), TEXT("Error"), MB_ICONERROR | MB_OK);
56  return 0;
57  }
58 
59  /* Load accelerators */
61 
62  /* Show main window and force a paint */
63  ShowWindow(hWnd, nCmdShow | SW_MAXIMIZE);
65 
66  /* Main message loop */
67  while (GetMessage(&msg, NULL, 0, 0) > 0)
68  {
69  if (!TranslateAccelerator(hWnd, hAccelerators, &msg))
70  {
73  }
74  }
75 
76  return (int)msg.wParam;
77 }
78 
79 /* Dialog procedure for our "about" dialog */
81 {
82  switch (uMsg)
83  {
84  case WM_COMMAND:
85  {
86  WORD id = LOWORD(wParam);
87 
88  switch (id)
89  {
90  case IDOK:
91  case IDCANCEL:
92  {
93  EndDialog(hwndDlg, (INT_PTR)id);
94  return (INT_PTR)TRUE;
95  }
96  }
97  break;
98  }
99 
100  case WM_INITDIALOG:
101  {
102  return (INT_PTR)TRUE;
103  }
104  }
105 
106  return (INT_PTR)FALSE;
107 }
108 
109 /* Show our "about" dialog */
111 {
113 }
114 
115 /* Main window class and title */
116 static LPCTSTR MainWndClass = TEXT("BiDi Test");
117 
118 /* Window procedure for our main window */
120 {
121  switch (msg)
122  {
123  case WM_COMMAND:
124  {
125  WORD id = LOWORD(wParam);
126 
127  switch (id)
128  {
129  case ID_HELP_ABOUT:
130  {
132  return 0;
133  }
134 
135  case ID_FILE_EXIT:
136  {
138  return 0;
139  }
140  }
141  break;
142  }
143 
144  case WM_GETMINMAXINFO:
145  {
146  /* Prevent our window from being sized too small */
147  MINMAXINFO *minMax = (MINMAXINFO*)lParam;
148  minMax->ptMinTrackSize.x = 220;
149  minMax->ptMinTrackSize.y = 110;
150 
151  return 0;
152  }
153 
154  /* Item from system menu has been invoked */
155  case WM_SYSCOMMAND:
156  {
157  WORD id = LOWORD(wParam);
158 
159  switch (id)
160  {
161  /* Show "about" dialog on about system menu item */
162  case ID_HELP_ABOUT:
163  {
165  return 0;
166  }
167  }
168  break;
169  }
170 
171  case WM_PAINT:
172  {
173  PAINTSTRUCT ps;
174 
175  HDC hdc = BeginPaint(hWnd, &ps);
176 
177  enum
178  {
179  ALEF = 0x5D0,
180  BET,
181  GIMEL,
182  DALET,
183  HEY,
184  VAV,
185  ZAYIN,
186  HET,
187  TET,
188  YUD
189  };
190 
191  const WCHAR szString[] = {ALEF, BET, GIMEL, DALET, HEY, 'A', 'B', 'C', 'D', VAV, ZAYIN, HET, TET, YUD, 0};
192  const WCHAR szReversedString[] = {HEY, DALET, GIMEL, BET, ALEF, 'A', 'B', 'C', 'D', YUD, TET, HET, ZAYIN, VAV, 0};
193  int Len = wcslen(szString);
194  int i, xpos, tempLength;
195  WCHAR tempString[20] = { 0 };
196  WCHAR Glyphs[100] = { 0 };
197  WCHAR OutString[100] = { 0 };
198  INT lpCaretPos[100] = { 0 };
199  UINT lpOrder[100] = { 0 };
200  GCP_RESULTSW Results = { 0 };
201 
202  Results.lStructSize = sizeof(Results);
203  Results.lpOutString = OutString;
204  Results.lpGlyphs = Glyphs;
205  Results.nGlyphs = 100;
206  Results.lpCaretPos = lpCaretPos;
207  Results.lpOrder = lpOrder;
208 
210 
211  TextOutW(hdc, 10, 10, L"Proper (string being used):", 27);
212  TextOutW(hdc, 200, 10, szString, 14);
213  TextOutW(hdc, 10, 30, L"Reversed (example):", 19);
214  TextOutW(hdc, 200, 30, szReversedString, 14);
215 
216  TextOutW(hdc, 10, 50, L"String with NULL LpkETO call (not reversed):", 44);
217  LpkExtTextOut(hdc, 10, 70, 0, NULL, szString, Len, NULL, 0);
218 
219  TextOutW(hdc, 10, 90, L"String with ETO_IGNORELANGUAGE LpkETO call (not reversed):", 58);
220  LpkExtTextOut(hdc, 10, 110, ETO_IGNORELANGUAGE, NULL, szString, Len, NULL, 0);
221 
222  TextOutW(hdc, 10, 130, L"String with GCP_REORDER and ETO_GLYPH_INDEX LpkGCP call (not reversed):", 71);
223  LpkGetCharacterPlacement(hdc, szString, Len, 0, &Results, GCP_REORDER, 0);
224  LpkExtTextOut(hdc, 10, 150, ETO_GLYPH_INDEX, NULL, Glyphs, Results.nGlyphs, NULL, 0);
225  TextOutW(hdc, 10, 170, L"String with GCP_REORDER and ETO_IGNORELANGUAGE LpkGCP call (not reversed, lpOutString):", 87);
226  ExtTextOutW(hdc, 10, 190, ETO_IGNORELANGUAGE, NULL, OutString, Results.nGlyphs, NULL);
227 
228  TextOutW(hdc, 10, 210, L"String without GCP_REORDER and ETO_GLYPH_INDEX LpkGCP call (reversed):", 70);
229  LpkGetCharacterPlacement(hdc, szString, Len, 0, &Results, 0, 0);
230  LpkExtTextOut(hdc, 10, 230, ETO_GLYPH_INDEX, NULL, Glyphs, Results.nGlyphs, NULL, 0);
231  TextOutW(hdc, 10, 250, L"String without GCP_REORDER and ETO_IGNORELANGUAGE LpkGCP call (reversed, lpOutString):", 86);
232  ExtTextOutW(hdc, 10, 270, ETO_IGNORELANGUAGE, NULL, OutString, Len, NULL);
233 
234  TextOutW(hdc, 10, 290, L"String with ETO_IGNORELANGUAGE ETO call (reversed, not Lpk direct call!):", 73);
235  ExtTextOutW(hdc, 10, 310, ETO_IGNORELANGUAGE, NULL, szString, Len, NULL);
236 
237  TextOutW(hdc, 10, 330, L"String with ETO_RTLREADING LpkETO call (slight order change)", 60);
238  LpkExtTextOut(hdc, 10, 350, ETO_RTLREADING, NULL, szString, Len, NULL, 0);
239 
240  TextOutW(hdc, 10, 370, L"String with ETO_RTLREADING ETO call (slight order change)", 57);
241  ExtTextOutW(hdc, 10, 390, ETO_RTLREADING, NULL, szString, Len, NULL);
242 
243  GetCharacterPlacementW(hdc, szString, Len, 0, &Results, GCP_REORDER);
244  TextOutW(hdc, 10, 410, L"Glyph positions with GCP_REORDER flag", 37);
245 
246  /* Prints per column the location of the character in the string, reordered location, its position and the character itself */
247  for (i = 0, xpos = 10; i < Len; i++, xpos += 30)
248  {
249  StringCchPrintfW(tempString, 20, L"%d", i);
250  tempLength = wcslen(tempString);
251  TextOutW(hdc, xpos, 430, tempString, tempLength);
252 
253  StringCchPrintfW(tempString, 20, L"%d", lpOrder[i]);
254  tempLength = wcslen(tempString);
255  TextOutW(hdc, xpos, 450, tempString, tempLength);
256 
257  StringCchPrintfW(tempString, 20, L"%d", lpCaretPos[i]);
258  tempLength = wcslen(tempString);
259  TextOutW(hdc, xpos, 470, tempString, tempLength);
260 
261  TextOutW(hdc, xpos, 490, &szString[i], 1);
262  }
263  TextOutW(hdc, xpos, 430, L"Character location", 18);
264  TextOutW(hdc, xpos, 450, L"lpOrder[i]", 10);
265  TextOutW(hdc, xpos, 470, L"lpCaretPos[i]", 13);
266  TextOutW(hdc, xpos, 490, L"String[i]", 9);
267 
268  GetCharacterPlacementW(hdc, szString, Len, 0, &Results, 0);
269  TextOutW(hdc, 10, 510, L"Glyph positions without GCP_REORDER flag", 40);
270 
271  for (i = 0, xpos = 10; i < Len; i++, xpos += 30)
272  {
273  StringCchPrintfW(tempString, 20, L"%d", i);
274  tempLength = wcslen(tempString);
275  TextOutW(hdc, xpos, 530, tempString, tempLength);
276 
277  StringCchPrintfW(tempString, 20, L"%d", lpOrder[i]);
278  tempLength = wcslen(tempString);
279  TextOutW(hdc, xpos, 550, tempString, tempLength);
280 
281  StringCchPrintfW(tempString, 20, L"%d", lpCaretPos[i]);
282  tempLength = wcslen(tempString);
283  TextOutW(hdc, xpos, 570, tempString, tempLength);
284 
285  TextOutW(hdc, xpos, 590, &szString[i], 1);
286  }
287  TextOutW(hdc, xpos, 530, L"Character location", 18);
288  TextOutW(hdc, xpos, 550, L"lpOrder[i]", 10);
289  TextOutW(hdc, xpos, 570, L"lpCaretPos[i]", 13);
290  TextOutW(hdc, xpos, 590, L"String[i]", 9);
291 
292  EndPaint(hWnd, &ps);
293  break;
294  }
295 
296  case WM_DESTROY:
297  {
298  PostQuitMessage(0);
299  return 0;
300  }
301  }
302 
303  return DefWindowProc(hWnd, msg, wParam, lParam);
304 }
305 
306 /* Register a class for our main window */
308 {
309  WNDCLASSEX wc;
310 
311  /* Class for our main window */
312  wc.cbSize = sizeof(wc);
313  wc.style = 0;
314  wc.lpfnWndProc = &MainWndProc;
315  wc.cbClsExtra = 0;
316  wc.cbWndExtra = 0;
317  wc.hInstance = g_hInstance;
321  wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
325 
326  return (RegisterClassEx(&wc)) ? TRUE : FALSE;
327 }
328 
329 /* Create an instance of our main window */
331 {
332  /* Create instance of main window */
335 
336  if (hWnd)
337  {
338  /* Add "about" to the system menu */
339  HMENU hSysMenu = GetSystemMenu(hWnd, FALSE);
340  InsertMenu(hSysMenu, 5, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
341  InsertMenu(hSysMenu, 6, MF_BYPOSITION, ID_HELP_ABOUT, TEXT("About"));
342  }
343 
344  return hWnd;
345 }
POINT ptMinTrackSize
Definition: winuser.h:3604
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
#define TranslateAccelerator
Definition: winuser.h:5761
UINT style
Definition: winuser.h:3176
#define MAKEINTRESOURCE
Definition: winuser.h:591
#define IDR_MAINMENU
Definition: resource.h:40
LPWSTR lpGlyphs
Definition: wingdi.h:2432
#define DispatchMessage
Definition: winuser.h:5666
BOOL WINAPI TranslateMessage(_In_ const MSG *)
static HICON
Definition: imagelist.c:84
LPCSTR lpszMenuName
Definition: winuser.h:3184
#define TRUE
Definition: types.h:120
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
#define IDOK
Definition: winuser.h:824
#define LR_SHARED
Definition: winuser.h:1090
#define IMAGE_ICON
Definition: winuser.h:212
#define RegisterClassEx
Definition: winuser.h:5738
Definition: kbdheb.c:78
_In_ int _Inout_ LPRECT lprc
Definition: winuser.h:4366
long y
Definition: polytest.cpp:48
HCURSOR hCursor
Definition: winuser.h:3182
WNDPROC lpfnWndProc
Definition: winuser.h:3177
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
long x
Definition: polytest.cpp:48
#define InsertMenu
Definition: winuser.h:5704
LPCSTR lpszClassName
Definition: winuser.h:3185
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define IMAGE_CURSOR
Definition: winuser.h:213
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:27
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
DWORD WINAPI GetCharacterPlacementW(_In_ HDC hdc, _In_reads_(nCount) LPCWSTR lpString, _In_ int nCount, _In_ int nMexExtent, _Inout_ LPGCP_RESULTSW lpResults, _In_ DWORD dwFlags)
DWORD lStructSize
Definition: wingdi.h:2426
static LPCTSTR MainWndClass
Definition: biditext.c:116
#define IDD_ABOUTDIALOG
Definition: biditext.h:29
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
UINT_PTR WPARAM
Definition: windef.h:207
HICON hIconSm
Definition: winuser.h:3186
HICON HCURSOR
Definition: windef.h:284
void ShowAboutDialog(HWND owner)
Definition: biditext.c:110
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
int32_t INT_PTR
Definition: typedefs.h:62
HINSTANCE g_hInstance
Definition: biditext.c:23
BOOL WINAPI DestroyWindow(_In_ HWND)
int32_t INT
Definition: typedefs.h:56
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
WPARAM wParam
Definition: combotst.c:138
CHAR * LPTSTR
Definition: xmlstorage.h:192
Definition: kbdheb.c:73
HWND CreateMainWindow()
Definition: biditext.c:330
INT_PTR CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: biditext.c:80
#define DialogBox
Definition: winuser.h:5662
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1032
#define LoadAccelerators
Definition: winuser.h:5711
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HINSTANCE hInstance
Definition: charmap.c:20
#define ICC_WIN95_CLASSES
Definition: commctrl.h:66
HINSTANCE hInstance
Definition: winuser.h:3180
unsigned int BOOL
Definition: ntddk_ex.h:94
#define MF_BYPOSITION
Definition: winuser.h:203
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
#define ID_FILE_EXIT
Definition: resource.h:47
#define CreateWindowEx
Definition: winuser.h:5656
#define TRANSPARENT
Definition: wingdi.h:949
#define CW_USEDEFAULT
Definition: winuser.h:225
#define ID_HELP_ABOUT
Definition: resource.h:77
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: biditext.c:119
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
smooth NULL
Definition: ftsmooth.c:416
#define MF_SEPARATOR
Definition: winuser.h:137
LONG_PTR LPARAM
Definition: windef.h:208
UINT cbSize
Definition: winuser.h:3175
HBRUSH hbrBackground
Definition: winuser.h:3183
#define DefWindowProc
Definition: ros2win.h:31
#define WM_DESTROY
Definition: winuser.h:1591
#define LR_DEFAULTSIZE
Definition: winuser.h:1084
__wchar_t WCHAR
Definition: xmlstorage.h:180
Definition: kbdheb.c:75
#define WINAPI
Definition: msvc.h:8
BOOL WINAPI LpkExtTextOut(HDC hdc, int x, int y, UINT fuOptions, const RECT *lprc, LPCWSTR lpString, UINT uCount, const INT *lpDx, INT unknown)
Definition: lpk.c:202
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
int cbWndExtra
Definition: winuser.h:3179
#define Len
Definition: deflate.h:82
Definition: id3.c:18
#define WM_PAINT
Definition: winuser.h:1602
LPWSTR lpOutString
Definition: wingdi.h:2427
Definition: kbdheb.c:77
HICON hIcon
Definition: winuser.h:3181
static const WCHAR L[]
Definition: oid.c:1250
HDC hdc
Definition: main.c:9
BOOL WINAPI InitCommonControlsEx(const INITCOMMONCONTROLSEX *lpInitCtrls)
Definition: commctrl.c:893
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define COLOR_BTNFACE
Definition: winuser.h:918
#define MB_ICONERROR
Definition: winuser.h:781
#define MessageBox
Definition: winuser.h:5723
#define WM_COMMAND
Definition: winuser.h:1722
BOOL WINAPI TextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCWSTR lpString, _In_ int c)
#define IDI_APPICON
Definition: resource.h:166
Definition: kbdheb.c:71
#define IDR_ACCELERATOR
Definition: resource.h:5
Definition: kbdheb.c:74
DWORD WINAPI LpkGetCharacterPlacement(HDC hdc, LPCWSTR lpString, INT uCount, INT nMaxExtent, GCP_RESULTSW *lpResults, DWORD dwFlags, DWORD dwUnused)
Definition: kbdheb.c:72
int cbClsExtra
Definition: winuser.h:3178
Definition: kbdheb.c:76
#define TEXT(s)
Definition: k32.h:26
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
unsigned int UINT
Definition: ndis.h:50
#define MB_OK
Definition: winuser.h:784
#define GetMessage
Definition: winuser.h:5691
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
Definition: kbdheb.c:79
#define msg(x)
Definition: auth_time.c:54
BOOL RegisterMainWindowClass()
Definition: biditext.c:307
#define IDC_ARROW
Definition: winuser.h:682
UINT * lpOrder
Definition: wingdi.h:2428
#define GCP_REORDER
Definition: wingdi.h:842
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int nCmdShow)
Definition: biditext.c:27
Definition: kbdheb.c:70
#define LoadImage
Definition: winuser.h:5716
#define IDCANCEL
Definition: winuser.h:825
LONG_PTR LRESULT
Definition: windef.h:209
#define LR_DEFAULTCOLOR
Definition: winuser.h:1077
#define SW_MAXIMIZE
Definition: winuser.h:766
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define WM_SYSCOMMAND
Definition: winuser.h:1723
#define WM_INITDIALOG
Definition: winuser.h:1721
LPARAM lParam
Definition: combotst.c:139
#define WM_GETMINMAXINFO
Definition: winuser.h:1622
#define LOWORD(l)
Definition: pedump.c:82
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
INT * lpCaretPos
Definition: wingdi.h:2430