| Viewing file:  layout.cpp (9.8 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
/********************************************************************************
 *
 *   © 2016 and later: Unicode, Inc. and others.
 *   License & terms of use: http://www.unicode.org/copyright.html#License
 *
 *******************************************************************************
 *******************************************************************************
 *
 *   Copyright (C) 1999-2007, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  Layout.cpp
 *
 *   created on: 08/03/2000
 *   created by: Eric R. Mader
 */
 
 #include <windows.h>
 #include <stdio.h>
 
 #include "paragraph.h"
 
 #include "GDIGUISupport.h"
 #include "GDIFontMap.h"
 #include "UnicodeReader.h"
 #include "ScriptCompositeFontInstance.h"
 
 #include "resource.h"
 
 #define ARRAY_LENGTH(array) (sizeof array / sizeof array[0])
 
 struct Context
 {
 le_int32 width;
 le_int32 height;
 Paragraph *paragraph;
 };
 
 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
 #define APP_NAME "LayoutSample"
 
 TCHAR szAppName[] = TEXT(APP_NAME);
 
 void PrettyTitle(HWND hwnd, char *fileName)
 {
 char title[MAX_PATH + 64];
 
 sprintf(title, "%s - %s", APP_NAME, fileName);
 
 SetWindowTextA(hwnd, title);
 }
 
 void InitParagraph(HWND hwnd, Context *context)
 {
 SCROLLINFO si;
 
 if (context->paragraph != NULL) {
 // FIXME: does it matter what we put in the ScrollInfo
 // if the window's been minimized?
 if (context->width > 0 && context->height > 0) {
 context->paragraph->breakLines(context->width, context->height);
 }
 
 si.cbSize = sizeof si;
 si.fMask = SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL;
 si.nMin = 0;
 si.nMax = context->paragraph->getLineCount() - 1;
 si.nPage = context->height / context->paragraph->getLineHeight();
 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
 }
 }
 
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 {
 HWND hwnd;
 HACCEL hAccel;
 MSG msg;
 WNDCLASS wndclass;
 LEErrorCode status = LE_NO_ERROR;
 
 wndclass.style         = CS_HREDRAW | CS_VREDRAW;
 wndclass.lpfnWndProc   = WndProc;
 wndclass.cbClsExtra    = 0;
 wndclass.cbWndExtra    = sizeof(LONG);
 wndclass.hInstance     = hInstance;
 wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
 wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
 wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
 wndclass.lpszMenuName  = szAppName;
 wndclass.lpszClassName = szAppName;
 
 if (!RegisterClass(&wndclass)) {
 MessageBox(NULL, TEXT("This demo only runs on Windows 2000!"), szAppName, MB_ICONERROR);
 
 return 0;
 }
 
 hAccel = LoadAccelerators(hInstance, szAppName);
 
 hwnd = CreateWindow(szAppName, NULL,
 WS_OVERLAPPEDWINDOW | WS_VSCROLL,
 CW_USEDEFAULT, CW_USEDEFAULT,
 600, 400,
 NULL, NULL, hInstance, NULL);
 
 ShowWindow(hwnd, iCmdShow);
 UpdateWindow(hwnd);
 
 while (GetMessage(&msg, NULL, 0, 0)) {
 if (!TranslateAccelerator(hwnd, hAccel, &msg)) {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
 }
 }
 
 UnregisterClass(szAppName, hInstance);
 return msg.wParam;
 }
 
 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
 HDC hdc;
 Context *context;
 static le_int32 windowCount = 0;
 static GDIFontMap *fontMap = NULL;
 static GDISurface *surface = NULL;
 static GDIGUISupport *guiSupport = new GDIGUISupport();
 static ScriptCompositeFontInstance *font = NULL;
 
 switch (message) {
 case WM_CREATE:
 {
 LEErrorCode fontStatus = LE_NO_ERROR;
 
 hdc = GetDC(hwnd);
 surface = new GDISurface(hdc);
 
 fontMap = new GDIFontMap(surface, "FontMap.GDI", 24, guiSupport, fontStatus);
 font    = new ScriptCompositeFontInstance(fontMap);
 
 if (LE_FAILURE(fontStatus)) {
 ReleaseDC(hwnd, hdc);
 return -1;
 }
 
 context = new Context();
 
 context->width  = 600;
 context->height = 400;
 
 context->paragraph = Paragraph::paragraphFactory("Sample.txt", font, guiSupport);
 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) context);
 
 windowCount += 1;
 ReleaseDC(hwnd, hdc);
 
 PrettyTitle(hwnd, "Sample.txt");
 return 0;
 }
 
 case WM_SIZE:
 {
 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
 context->width  = LOWORD(lParam);
 context->height = HIWORD(lParam);
 
 InitParagraph(hwnd, context);
 return 0;
 }
 
 case WM_VSCROLL:
 {
 SCROLLINFO si;
 le_int32 vertPos;
 
 si.cbSize = sizeof si;
 si.fMask = SIF_ALL;
 GetScrollInfo(hwnd, SB_VERT, &si);
 
 vertPos = si.nPos;
 
 switch (LOWORD(wParam))
 {
 case SB_TOP:
 si.nPos = si.nMin;
 break;
 
 case SB_BOTTOM:
 si.nPos = si.nMax;
 break;
 
 case SB_LINEUP:
 si.nPos -= 1;
 break;
 
 case SB_LINEDOWN:
 si.nPos += 1;
 break;
 
 case SB_PAGEUP:
 si.nPos -= si.nPage;
 break;
 
 case SB_PAGEDOWN:
 si.nPos += si.nPage;
 break;
 
 case SB_THUMBTRACK:
 si.nPos = si.nTrackPos;
 break;
 
 default:
 break;
 }
 
 si.fMask = SIF_POS;
 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
 GetScrollInfo(hwnd, SB_VERT, &si);
 
 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
 
 if (context->paragraph != NULL && si.nPos != vertPos) {
 ScrollWindow(hwnd, 0, context->paragraph->getLineHeight() * (vertPos - si.nPos), NULL, NULL);
 UpdateWindow(hwnd);
 }
 
 return 0;
 }
 
 case WM_PAINT:
 {
 PAINTSTRUCT ps;
 SCROLLINFO si;
 le_int32 firstLine, lastLine;
 
 hdc = BeginPaint(hwnd, &ps);
 SetBkMode(hdc, TRANSPARENT);
 
 si.cbSize = sizeof si;
 si.fMask = SIF_ALL;
 GetScrollInfo(hwnd, SB_VERT, &si);
 
 firstLine = si.nPos;
 
 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
 
 if (context->paragraph != NULL) {
 surface->setHDC(hdc);
 
 // NOTE: si.nPos + si.nPage may include a partial line at the bottom
 // of the window. We need this because scrolling assumes that the
 // partial line has been painted.
 lastLine  = min (si.nPos + (le_int32) si.nPage, context->paragraph->getLineCount() - 1);
 
 context->paragraph->draw(surface, firstLine, lastLine);
 }
 
 EndPaint(hwnd, &ps);
 return 0;
 }
 
 case WM_COMMAND:
 switch (LOWORD(wParam)) {
 case IDM_FILE_OPEN:
 {
 OPENFILENAMEA ofn;
 char szFileName[MAX_PATH], szTitleName[MAX_PATH];
 static char szFilter[] = "Text Files (.txt)\0*.txt\0"
 "All Files (*.*)\0*.*\0\0";
 
 ofn.lStructSize       = sizeof (OPENFILENAMEA);
 ofn.hwndOwner         = hwnd;
 ofn.hInstance         = NULL;
 ofn.lpstrFilter       = szFilter;
 ofn.lpstrCustomFilter = NULL;
 ofn.nMaxCustFilter    = 0;
 ofn.nFilterIndex      = 0;
 ofn.lpstrFile         = szFileName;
 ofn.nMaxFile          = MAX_PATH;
 ofn.lpstrFileTitle    = szTitleName;
 ofn.nMaxFileTitle     = MAX_PATH;
 ofn.lpstrInitialDir   = NULL;
 ofn.lpstrTitle        = NULL;
 ofn.Flags             = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
 ofn.nFileOffset       = 0;
 ofn.nFileExtension    = 0;
 ofn.lpstrDefExt       = "txt";
 ofn.lCustData         = 0L;
 ofn.lpfnHook          = NULL;
 ofn.lpTemplateName    = NULL;
 
 szFileName[0] = '\0';
 
 if (GetOpenFileNameA(&ofn)) {
 hdc = GetDC(hwnd);
 surface->setHDC(hdc);
 
 Paragraph *newParagraph = Paragraph::paragraphFactory(szFileName, font, guiSupport);
 
 if (newParagraph != NULL) {
 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
 
 if (context->paragraph != NULL) {
 delete context->paragraph;
 }
 
 context->paragraph = newParagraph;
 InitParagraph(hwnd, context);
 PrettyTitle(hwnd, szTitleName);
 InvalidateRect(hwnd, NULL, TRUE);
 
 }
 }
 
 //ReleaseDC(hwnd, hdc);
 
 return 0;
 }
 
 case IDM_FILE_EXIT:
 case IDM_FILE_CLOSE:
 SendMessage(hwnd, WM_CLOSE, 0, 0);
 return 0;
 
 case IDM_HELP_ABOUTLAYOUTSAMPLE:
 MessageBox(hwnd, TEXT("Windows Layout Sample 0.1\n")
 TEXT("Copyright (C) 1998-2005 By International Business Machines Corporation and others.\n")
 TEXT("Author: Eric Mader"),
 szAppName, MB_ICONINFORMATION | MB_OK);
 return 0;
 
 }
 break;
 
 
 case WM_DESTROY:
 {
 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
 
 if (context != NULL && context->paragraph != NULL) {
 delete context->paragraph;
 }
 
 delete context;
 
 if (--windowCount <= 0) {
 delete font;
 delete surface;
 
 PostQuitMessage(0);
 }
 
 return 0;
 }
 
 default:
 return DefWindowProc(hwnd, message, wParam, lParam);
 }
 
 return 0;
 }
 
 |