Advertisement
Guest User

Untitled

a guest
Nov 26th, 2014
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.43 KB | None | 0 0
  1. #include <windows.h>
  2. #include "StdAfx.h"
  3. #include "strsafe.h"
  4. #include <Commdlg.h>
  5.  
  6. #include <strsafe.h>
  7. #pragma comment(lib, "strsafe.lib")
  8.  
  9.  
  10. #define ID_FILE_EXIT 9001
  11. #define ID_STUFF_GO 9002
  12.  
  13. #define ID_FIRSTNAME 303
  14. #define ID_LASTNAME 304
  15. #define ID_NAME 305
  16. #define ID_DEVSTAT 306
  17. #define ID_LEARNFORM 307
  18. #define ID_GROUP 308
  19.  
  20. #define FONT 309
  21.  
  22.     #define BUFSIZE 65535
  23. #define SHIFTED 0x8000
  24.  
  25.  
  26. HGDIOBJ g_hfFont = GetStockObject(GRAY_BRUSH);
  27.             COLORREF g_rgbText = RGB(0, 0, 0);
  28.  
  29. HFONT hf;
  30. int lfHeight;
  31.  
  32. //LRESULT CALLBACK
  33.  
  34. LRESULT CALLBACK MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam, LPARAM lParam)
  35. {
  36.     HDC hdc;                   // дескриптор контекста устройства
  37.     TEXTMETRIC tm;             // структура для текстовой метрики
  38.     static DWORD dwCharX;      // средняя ширина символа
  39.     static DWORD dwCharY;      // высота символа
  40.     static DWORD dwClientX;    // ширина рабочей области
  41.     static DWORD dwClientY;    // высота рабочей области
  42.     static DWORD dwLineLen;    // длина строки
  43.     static DWORD dwLines;      // строки текста в рабочей области
  44.     static int nCaretPosX = 0; // горизонтальная позиция каретки
  45.     static int nCaretPosY = 0; // вертикальная позиция каретки
  46.     static int nCharWidth = 0; // ширина символа
  47.     static int cch = 0;        // символы в буфере
  48.     static int nCurChar = 0;   // индекс текущего символа
  49.     static PTCHAR pchInputBuf; // буфер ввода
  50.     int i, j;                  // цикл счета
  51.     int cCR = 0;               // счетчик переводов каретки
  52.     int nCRIndex = 0;          // индекс последнего перевода каретки
  53.     int nVirtKey;              // код виртуальной клавиши
  54.     TCHAR szBuf[128];          // временный буфер
  55.     TCHAR ch;                  // текущий символ
  56.     PAINTSTRUCT ps;            // требуется для BeginPaint
  57.     RECT rc;                   // прямоугольник вывода для DrawText
  58.     SIZE sz;                   // размеры строк
  59.     COLORREF crPrevText;       // предыдущий цвет текста
  60.     COLORREF crPrevBk;         // предыдущий цвет фона
  61.     size_t * pcch;
  62.     HRESULT hResult;
  63.  
  64.     switch (uMsg)
  65.     {
  66.         case WM_CREATE:
  67.  
  68.                     hdc = GetDC(hwndMain);
  69.             lfHeight = -MulDiv(16, GetDeviceCaps(hdc, LOGPIXELSY), 72);
  70.            
  71.             hf = CreateFont(lfHeight, 0, 0, 0, FW_BOLD, TRUE, 0, 0, 0, 0, 0, 0, 0, TEXT("Tahoma"));
  72.             // Получим метрику текущего шрифта.
  73.  
  74.    
  75.             GetTextMetrics(hdc, &tm);
  76.             ReleaseDC(hwndMain, hdc);
  77.  
  78.             // Сохраним среднюю ширину и высоту символа.
  79.  
  80.             dwCharX = tm.tmAveCharWidth;
  81.             dwCharY = tm.tmHeight;
  82.  
  83.             // Назначим в памяти буфер для ввода информации с клавиатуры.
  84.  
  85.             pchInputBuf = (LPTSTR) GlobalAlloc(GPTR,
  86.                 BUFSIZE * sizeof(TCHAR));
  87.  
  88.  
  89.  
  90.             HMENU hMenu, hSubMenu;
  91. hMenu = CreateMenu();
  92. hSubMenu = CreatePopupMenu();
  93. AppendMenu(hSubMenu, MF_STRING, ID_FIRSTNAME , "FirstName");
  94. AppendMenu(hSubMenu, MF_STRING, ID_LASTNAME , "LastName");
  95. AppendMenu(hSubMenu, MF_STRING, ID_NAME , "Name");
  96. AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&FIO");
  97. hSubMenu = CreatePopupMenu();
  98. AppendMenu(hSubMenu, MF_STRING, ID_DEVSTAT , "DeveloperStatus");
  99. AppendMenu(hSubMenu, MF_STRING, ID_LEARNFORM , "LearningForm");
  100. AppendMenu(hSubMenu, MF_STRING, ID_GROUP , "Group");
  101. AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&INFO");
  102. AppendMenu(hSubMenu, MF_STRING, FONT, "Шрифт");
  103. //AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Шрифт");
  104. SetMenu(hwndMain, hMenu);
  105.             return 0;
  106.                 case WM_COMMAND:
  107.                 switch(LOWORD(wParam))
  108.                 {
  109.                 case FONT:
  110.                 HFONT DoSelectFont(HWND,HFONT);
  111.                 hf=DoSelectFont(hwndMain,hf);
  112.                 break;
  113. }
  114.         case WM_SIZE:
  115.  
  116.             // Сохраним новую ширину и высоту рабочей области.
  117.  
  118.             dwClientX = LOWORD(lParam);
  119.             dwClientY = HIWORD(lParam);
  120.  
  121.             // Вычислим максимальную ширину строки и
  122.             // максимальное число строк в рабочей области.
  123.            
  124.             dwLineLen = dwClientX - dwCharX;
  125.             dwLines = dwClientY / dwCharY;
  126.             break;
  127.  
  128.  
  129.         case WM_SETFOCUS:
  130.  
  131.             // Создадим, позиционируем и отобразим каретку в окне,
  132.             // которое получило фокус ввода клавиатуры.
  133.  
  134.             CreateCaret(hwndMain, (HBITMAP) 1, 3, dwCharY);
  135.             SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
  136.             ShowCaret(hwndMain);
  137.             break;
  138.  
  139.         case WM_KILLFOCUS:
  140.  
  141.             // Скроем и разрушим каретку,
  142.             // когда окно теряет фокус ввода с клавиатуры.
  143.  
  144.             HideCaret(hwndMain);
  145.             DestroyCaret();
  146.             break;
  147.  
  148.         case WM_CHAR:
  149.         // проверяем, если текущее место достаточно близко
  150.         // к концу буфера, что может привести к переполнению
  151.         // его. Если это так, то добавляем нуль и показываем
  152.                 // содержимое.
  153.                
  154.     if (cch > BUFSIZE-5)
  155.     {
  156.         pchInputBuf[cch] = 0x00;
  157.         SendMessage(hwndMain, WM_PAINT, 0, 0);
  158.     }
  159.             switch (wParam)
  160.             {
  161.                 case 0x08:  // возврат каретки
  162.                 case 0x0A:  // перевод строки
  163.                 case 0x1B:  // escape
  164.                     MessageBeep((UINT) -1);
  165.                     return 0;
  166.  
  167.                 case 0x09:  // табуляция
  168.  
  169.                     // Преобразование табуляции в четыре последовательных пробела.
  170.  
  171.                     for (i = 0; i < 4; i++)
  172.                         SendMessage(hwndMain, WM_CHAR, 0x20, 0);
  173.                     return 0;
  174.  
  175.                 case 0x0D:  // возврат каретки
  176.  
  177.                     // Запись перевода каретки и позиции
  178.                     // каретки в начале новой строки.
  179.  
  180.                     pchInputBuf[cch++] = 0x0D;
  181.                     nCaretPosX = 0;
  182.                     nCaretPosY += 1;
  183.                     break;
  184.  
  185.                 default:    // отображаемый символ
  186.  
  187.                     ch = (TCHAR) wParam;
  188.                     HideCaret(hwndMain);
  189.  
  190.                     // Извлечение данных о ширине
  191.                     // символа и вывод символа.
  192.  
  193.                     hdc = GetDC(hwndMain);
  194.                     GetCharWidth32(hdc, (UINT) wParam, (UINT) wParam,
  195.                         &nCharWidth);
  196.                     DrawText(hdc, pchInputBuf, -1, &rc, DT_LEFT);
  197.                     InvalidateRect(hwndMain,NULL,true);
  198.                     //TextOut(hdc, nCaretPosX, nCaretPosY * dwCharY,
  199.                    //     &ch, 1);
  200.                     SendMessage(hwndMain,WM_PAINT,NULL,NULL);
  201.                     ReleaseDC(hwndMain, hdc);
  202.  
  203.                     // Сохранение символа в буфере.
  204.  
  205.                     pchInputBuf[cch++] = ch;
  206.  
  207.                     // Вычисление новой горизонтальной позиции каретки.
  208.                     // Если позиция превышает максимум, вставьте перевод
  209.                     // каретки, и переместите каретку в начало
  210.                     // следующей строки.
  211.  
  212.                     nCaretPosX += nCharWidth;
  213.                     if ((DWORD) nCaretPosX > dwLineLen)
  214.                     {
  215.                         nCaretPosX = 0;
  216.                         pchInputBuf[cch++] = 0x0D;
  217.                         ++nCaretPosY;
  218.                     }
  219.                     nCurChar = cch;
  220.                     ShowCaret(hwndMain);
  221.                     break;
  222.             }
  223.             SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
  224.             break;
  225.  
  226.         case WM_KEYDOWN:
  227.             switch (wParam)
  228.             {
  229.                 case VK_LEFT:   // LEFT ARROW
  230.  
  231.                     // Каретка может перемещаться только в начало
  232.                     // текущей строки.
  233.  
  234.                     if (nCaretPosX > 0)
  235.                     {
  236.                         HideCaret(hwndMain);
  237.  
  238.                         // Извлекает данные о символе слева от каретки,
  239.                         // вычисляет ширину символа, а  затем вычитает
  240.                         // ширину из текущей горизонтальной позиции
  241.                         // каретки, чтобы получить
  242.                         // новую позицию.
  243.  
  244.                         ch = pchInputBuf[--nCurChar];
  245.                         hdc = GetDC(hwndMain);
  246.                         GetCharWidth32(hdc, ch, ch, &nCharWidth);
  247.                         ReleaseDC(hwndMain, hdc);
  248.                         nCaretPosX = max(nCaretPosX - nCharWidth,
  249.                             0);
  250.                         ShowCaret(hwndMain);
  251.                     }
  252.                     break;
  253.  
  254.                 case VK_RIGHT:  // Клавиша RIGHT ARROW (стрелка вправо)
  255.  
  256.                     // Каретка перемещается вправо или,  когда
  257.                     // определяется перевод каретки, чтобы
  258.                     // начать следующую строку.
  259.  
  260.                     if (nCurChar < cch)
  261.                     {
  262.                         HideCaret(hwndMain);
  263.  
  264.                         // Извлекаем данные о символе справа
  265.                         // от каретки. Если они являются переводом
  266.                         // каретки, каретка позиционируется
  267.                         // в начале следующей строки.
  268.  
  269.                         ch = pchInputBuf[nCurChar];
  270.                         if (ch == 0x0D)
  271.                         {
  272.                             nCaretPosX = 0;
  273.                             nCaretPosY++;
  274.                         }
  275.  
  276.                         // Если символ не является переводом каретки,
  277.                         // возвращаемся, проверяем, не нажата ли
  278.                         // клавиша SHIFT. Если она нажата,  
  279.                         // инвертируем цвет текста и выводим символ.
  280.  
  281.                         else
  282.                         {
  283.                             hdc = GetDC(hwndMain);
  284.                             nVirtKey = GetKeyState(VK_SHIFT);
  285.                             if (nVirtKey & SHIFTED)
  286.                             {
  287.                                 crPrevText = SetTextColor(hdc,
  288.                                     RGB(255, 255, 255));
  289.                                 crPrevBk = SetBkColor(hdc,
  290.                                     RGB(0,0,0));
  291.                                 TextOut(hdc, nCaretPosX,
  292.                                     nCaretPosY * dwCharY,
  293.                                     &ch, 1);
  294.                                 SetTextColor(hdc, crPrevText);
  295.                                 SetBkColor(hdc, crPrevBk);
  296.                             }
  297.  
  298.                             // Получаем ширину символа и
  299.                             // вычисляем новую горизонтальную
  300.                             // позицию каретки.
  301.  
  302.                             GetCharWidth32(hdc, ch, ch, &nCharWidth);
  303.                             ReleaseDC(hwndMain, hdc);
  304.                             nCaretPosX = nCaretPosX + nCharWidth;
  305.                         }
  306.                         nCurChar++;
  307.                         ShowCaret(hwndMain);
  308.                         break;
  309.                     }
  310.                     break;
  311.  
  312.                 case VK_UP:     // Клавиша UP ARROW
  313.                 case VK_DOWN:   // Клавиша DOWN ARROW
  314.                     MessageBeep((UINT) -1);
  315.                     return 0;
  316.  
  317.                 case VK_HOME:   // Клавиша HOME
  318.  
  319.                     // Устанавливаем позицию каретки в верхнем левом
  320.                     // углу рабочей области.
  321.  
  322.                     nCaretPosX = nCaretPosY = 0;
  323.                     nCurChar = 0;
  324.                     break;
  325.  
  326.                 case VK_END:    // Клавиша END  
  327.  
  328.                     // Перемещаем каретку в конец текста.
  329.  
  330.                     for (i=0; i < cch; i++)
  331.                     {
  332.                         // Считаем число переводов каретки и
  333.                         // сохраняем индекс последнего счета.
  334.  
  335.                         if (pchInputBuf[i] == 0x0D)
  336.                         {
  337.                             cCR++;
  338.                             nCRIndex = i + 1;
  339.                         }
  340.                     }
  341.                     nCaretPosY = cCR;
  342.  
  343.                     // Копируем весь текст между последним переводом
  344.                     // каретки и концом из буфера
  345.                     // ввода с клавиатуры во временный буфер.
  346.  
  347.                     for (i = nCRIndex, j = 0; i < cch; i++, j++)
  348.                         szBuf[j] = pchInputBuf[i];
  349.                     szBuf[j] = TEXT('\0');
  350.  
  351.                     // Извлекаем данные о протяженности текста
  352.                     // и используем их, чтобы установить
  353.                     // горизонтальную позицию каретки.
  354.  
  355.                     //hdc = GetDC(hwndMain);
  356.                     GetTextExtentPoint32(hdc, szBuf, lstrlen(szBuf),&sz);
  357.                          
  358.                     nCaretPosX = sz.cx;
  359.                     ReleaseDC(hwndMain, hdc);
  360.                     nCurChar = cch;
  361.                     break;
  362.  
  363.                 default:
  364.                     break;
  365.             }
  366.             SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
  367.             break;
  368.  
  369.         case WM_PAINT:
  370.             if (cch == 0)       // в буфере ввода ничего нет
  371.                 break;
  372.  
  373.             hdc = BeginPaint(hwndMain, &ps);
  374.             HideCaret(hwndMain);
  375.  
  376.             // Установим прямоугольник отсечения, а затем
  377.             // пропишем текст внутри него.
  378.            
  379.            
  380.             SelectObject(hdc, hf);
  381.  
  382.             SetRect(&rc, 0, 0, dwLineLen, dwClientY);
  383.             DrawText(hdc, pchInputBuf, -1, &rc, DT_LEFT);
  384.  
  385.             ShowCaret(hwndMain);
  386.             EndPaint(hwndMain, &ps);
  387.             break;
  388.        
  389.         // Обработка других сообщений.
  390.        
  391.         case WM_DESTROY:
  392.             PostQuitMessage(0);
  393.  
  394.             // Освобождаем буфер ввода.
  395.  
  396.             GlobalFree((HGLOBAL) pchInputBuf);
  397.             UnregisterHotKey(hwndMain, 0xAAAA);
  398.             break;
  399.  
  400.         default:
  401.             return DefWindowProc(hwndMain, uMsg, wParam, lParam);
  402.     }
  403.     return NULL;
  404. }
  405.  
  406.  
  407.  
  408.         int APIENTRY WinMain(HINSTANCE hInstance,
  409.                 HINSTANCE hPrevInstance,
  410.                 LPSTR lpCmdLine,
  411.                 int nCmdShow)
  412.         {
  413.     WNDCLASSEX wc;
  414.     const char g_szClassName[] = "laba1Class";
  415.     HWND hwnd;
  416.     MSG msg;
  417.  
  418.     wc.cbSize = sizeof(WNDCLASSEX);
  419.     wc.style = CS_VREDRAW | CS_HREDRAW;
  420.     wc.lpfnWndProc=MainWndProc;
  421.     wc.cbClsExtra = 0;
  422.     wc.cbWndExtra = 0;
  423.     wc.hInstance = hInstance;
  424.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  425.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  426.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  427.     wc.lpszMenuName = NULL;
  428.     wc.lpszClassName = g_szClassName;
  429.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  430.     if(!RegisterClassEx(&wc))
  431.     {
  432.         MessageBox(NULL, "Window Registration Failed! ", "Error!", MB_ICONEXCLAMATION | MB_OK);
  433.         return 0;
  434.     }
  435.  
  436.     hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, g_szClassName, "Берман И., Антипин А.",
  437.             WS_OVERLAPPEDWINDOW&~WS_THICKFRAME , 200, 100, 800, 600, NULL, NULL,
  438.         hInstance, NULL);
  439.  
  440.     if(hwnd == NULL)
  441.     {
  442.         MessageBox(NULL, "Window Creation Failed! ", "Error!", MB_ICONEXCLAMATION | MB_OK);
  443.         return 0;
  444.     }
  445.  
  446.     ShowWindow(hwnd, nCmdShow);
  447.     UpdateWindow(hwnd);
  448.    
  449.     while(GetMessage(&msg, NULL, 0, 0) > 0)
  450.     {
  451.         TranslateMessage(&msg);
  452.  
  453.         DispatchMessage(&msg);
  454.         SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 500 /*width*/, 500 /*height*/, SWP_NOMOVE);
  455.     }
  456.     return msg.wParam;
  457. }
  458.  
  459.  
  460.  
  461.     /*  HMENU hMenu, hSubMenu;
  462.                     HICON hIcon, hIconSm;
  463.                     hMenu = CreateMenu();
  464.                     hSubMenu = CreatePopupMenu();
  465.                     AppendMenu(hSubMenu, MF_STRING, ID_FIO_FIRST, "FirstName");
  466.                     AppendMenu(hSubMenu, MF_STRING, ID_FIO_LAST, "SecondName");
  467.                     AppendMenu(hSubMenu, MF_STRING, ID_FIO_NAME, "Name");
  468.                     AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "FIO");
  469.                     hSubMenu = CreatePopupMenu();
  470.                     AppendMenu(hSubMenu, MF_STRING, ID_INFO_DEV, "DeveloperStatus");
  471.                     AppendMenu(hSubMenu, MF_STRING, ID_INFO_FORM, "LearningForm");
  472.                     AppendMenu(hSubMenu, MF_STRING, ID_INFO_GROUP, "Group");
  473.                     AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "INFO");
  474.                     SetMenu(hwndMain, hMenu);
  475.                     hIcon = (HICON)LoadImage(NULL, "my_icon.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
  476.                     if(hIcon)
  477.                         SendMessage(hwndMain, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
  478.                     else
  479.                         MessageBox(hwndMain, "Could not load large icon!", "Error", MB_OK | MB_ICONERROR);
  480.                     hIconSm = (HICON)LoadImage(NULL, "my_icon.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
  481.                     if(hIconSm)
  482.                         SendMessage(hwndMain, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
  483.                     else
  484.                         MessageBox(hwndMain, "Could not load small icon!", "Error", MB_OK | MB_ICONERROR);
  485.  
  486.  
  487.                     case WM_COMMAND:
  488.                     switch(LOWORD(wParam))
  489.                     {
  490.                         case ID_INFO_DEV:
  491.                             MessageBox(NULL, "Статус разработчиков - студенты", "Статус", 0);
  492.                             break;
  493.                         case ID_INFO_FORM:
  494.                             MessageBox(hwndMain, "Бакалавриат", "Антипин, Берман", 0);
  495.                             break;
  496.                         case ID_INFO_GROUP:
  497.                             MessageBox(hwndMain, "3143", "Антипин,Берман", 0);
  498.                             break;
  499.                         case ID_FIO_FIRST:
  500.                             MessageBox(hwndMain, "Артём, Иван", "Антипин, Берман", 0);
  501.                             break;
  502.                         case ID_FIO_LAST:
  503.                             MessageBox(hwndMain, "Антипин и Берман", "Антипин, Берман", 0);
  504.                             break;
  505.                         case ID_FIO_NAME:
  506.                             MessageBox(hwndMain, "Артём и Иван", "Антипин, Берман", 0);
  507.                             break;
  508.                         default:
  509.                             break;
  510.                     }
  511.                                     break;*/
  512.  
  513.  
  514.         /*          //  for( i = nCurChar, j = n; i < cch; i++, j++)
  515.                     //      Res[j] = pchInputBuf[i];
  516.                     //  n = j;
  517.                        
  518.  
  519.                     //cch = nCurChar;
  520.  
  521.                     pchInputBuf[cch++] = ch;
  522.                 //  ;//nCurChar++
  523.                    
  524.  
  525.                 //  for(i = nCurChar, j = 0; j < n; i++, j++)
  526.                 //      pchInputBuf[i] = Res[j];
  527.                     //}
  528.                     //else
  529.                         //pchInputBuf[cch++] = ch;
  530.  
  531.  
  532.                         for (i = nCRIndex, j = 0; i < cch; i++, j++)
  533.                         szBuf[j] = pchInputBuf[i];
  534.                     szBuf[j] = TEXT('\0');
  535.  
  536.                     // Извлекаем данные о протяженности текста
  537.                     // и используем их, чтобы установить
  538.                     // горизонтальную позицию каретки.
  539.  
  540.                     //hdc = GetDC(hwndMain);
  541.                     GetTextExtentPoint32(hdc, szBuf, lstrlen(szBuf),&sz);
  542.                          
  543.                     nCaretPosX = sz.cx;
  544.                     ReleaseDC(hwndMain, hdc);
  545.                     nCurChar = cch;
  546.                     break; */
  547.  
  548.  
  549. HFONT DoSelectFont(HWND hwnd, HFONT mhf)
  550. {
  551.     CHOOSEFONT cf;
  552.     LOGFONT lf;
  553.  
  554.     GetObject(mhf, sizeof(LOGFONT), &lf);
  555.     cf.lStructSize = sizeof(CHOOSEFONT);
  556.     cf.Flags = CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
  557.     cf.hwndOwner = hwnd;
  558.     cf.lpLogFont = &lf;
  559.     //cf.rgbColors = RGB(10, 20, 100);
  560.  
  561.     if (ChooseFont(&cf))
  562.     {
  563.     mhf = CreateFontIndirect(&lf);
  564.         if (!mhf)
  565.         {
  566.             MessageBox(hwnd, TEXT("Font creation failed!"), TEXT("Error"), MB_OK | MB_ICONEXCLAMATION);
  567.         }
  568.     }
  569.     hf=mhf;
  570.     return mhf;
  571. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement