home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 March / CMCD0304.ISO / Software / Freeware / Programare / nullsoft / nsis20.exe / Contrib / BgImage / BgImage.cpp next >
C/C++ Source or Header  |  2003-11-14  |  17KB  |  651 lines

  1. #include <Windows.h>
  2. #include <Mmsystem.h>
  3. #include "../exdll/exdll.h"
  4.  
  5. #undef EXDLL_INIT
  6.  
  7. #define EXDLL_INIT() {  \
  8.         g_stringsize=string_size; \
  9.         g_stacktop=stacktop; }
  10.  
  11. #define NSISFunc(name) extern "C" void __declspec(dllexport) name(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
  12.  
  13. char szTemp[2048];
  14. HWND hWndImage, hWndParent;
  15.  
  16. HINSTANCE g_hInstance;
  17.  
  18. CRITICAL_SECTION CriticalSection;
  19.  
  20. void ECS() {
  21.   EnterCriticalSection(&CriticalSection);
  22. }
  23.  
  24. void LCS() {
  25.   LeaveCriticalSection(&CriticalSection);
  26. }
  27.  
  28. enum {
  29.   MIL_DUMMY,
  30.   MIL_GRADIENT,
  31.   MIL_BITMAP,
  32.   MIL_TRANSPARENT_BITMAP,
  33.   MIL_TEXT
  34. };
  35.  
  36. struct myImageList {
  37.   BYTE iType;
  38.   union {
  39.     HBITMAP hBitmap;
  40.     char *szText;
  41.     COLORREF cGradientFrom;
  42.   };
  43.   RECT rPos;
  44.   union {
  45.     COLORREF cTransparent;
  46.     COLORREF cTextColor;
  47.     COLORREF cGradientTo;
  48.   };
  49.   HFONT hFont;
  50.  
  51.   BOOL bReady;
  52.  
  53.   myImageList *next;
  54. } bgBitmap;
  55.  
  56. unsigned int uWndWidth, uWndHeight;
  57.  
  58. void *oldProc;
  59. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  60. HBITMAP __stdcall LoadBitmapFile(long right, long bottom, BITMAP *bBitmap);
  61. int __stdcall myatoi(char *s);
  62. COLORREF GetColor();
  63. void __stdcall GetXY(LPPOINT lpPoint);
  64.  
  65. BOOL bReturn;
  66.  
  67. NSISFunc(SetReturn) {
  68.   EXDLL_INIT();
  69.  
  70.   popstring(szTemp);
  71.   bReturn = !lstrcmpi(szTemp, "on");
  72. }
  73.  
  74. static void __stdcall my_pushstring(char *str)
  75. {
  76.   stack_t *th;
  77.   if (!g_stacktop || !bReturn) return;
  78.   th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
  79.   lstrcpyn(th->text,str,g_stringsize);
  80.   th->next=*g_stacktop;
  81.   *g_stacktop=th;
  82. }
  83.  
  84. NSISFunc(SetBg) {
  85.   EXDLL_INIT();
  86.  
  87.   ECS();
  88.  
  89.   if (!hWndImage) {
  90.     hWndParent = hwndParent;
  91.  
  92.     if (!hwndParent) {
  93.       my_pushstring("can't find parent window");
  94.       LCS();
  95.       return;
  96.     }
  97.  
  98.     WNDCLASSEX wc = {
  99.       sizeof(WNDCLASSEX),
  100.       CS_VREDRAW|CS_HREDRAW,
  101.       WndProc,
  102.       0,
  103.       0,
  104.       g_hInstance,
  105.       0,
  106.       LoadCursor(0, IDC_ARROW),
  107.       0,
  108.       0,
  109.       "NSISBGImage",
  110.       0
  111.     };
  112.     ATOM atomClass = RegisterClassEx(&wc);
  113.     if (!atomClass) {
  114.       my_pushstring("can't create window");
  115.       return;
  116.     }
  117.  
  118.     hWndImage = CreateWindowEx(
  119.       WS_EX_TOOLWINDOW,
  120.       (LPSTR)atomClass,
  121.       0,
  122.       WS_CLIPSIBLINGS|WS_POPUP,
  123.       0,
  124.       0,
  125.       0,
  126.       0,
  127.       0,
  128.       0,
  129.       g_hInstance,
  130.       0
  131.     );
  132.     if (!hWndImage) {
  133.       my_pushstring("can't create window");
  134.       LCS();
  135.       return;
  136.     }
  137.  
  138.     oldProc = (void *)SetWindowLong(hwndParent, GWL_WNDPROC, (long)WndProc);
  139.   }
  140.  
  141.   bgBitmap.bReady = FALSE;
  142.  
  143.   if (bgBitmap.iType == MIL_BITMAP)
  144.     DeleteObject(bgBitmap.hBitmap);
  145.  
  146.   unsigned int uScrWidth = GetSystemMetrics(SM_CXSCREEN);
  147.   unsigned int uScrHeight = GetSystemMetrics(SM_CYSCREEN);
  148.  
  149.   bgBitmap.iType = MIL_BITMAP;
  150.   bgBitmap.rPos.right = 0;
  151.   bgBitmap.rPos.bottom = 0;
  152.   uWndWidth = uScrWidth;
  153.   uWndHeight = uScrHeight;
  154.  
  155.   char szGradient[] = {'/', 'G', 'R', 'A', 'D', 'I', 'E', 'N', 'T', 0};
  156.   char szFillScreen[] = {'/', 'F', 'I' ,'L', 'L', 'S', 'C', 'R', 'E', 'E', 'N', 0};
  157.   char szTiled[] = {'/', 'T', 'I', 'L', 'E', 'D', 0};
  158.  
  159.   popstring(szTemp);
  160.   if (!lstrcmpi(szTemp, szGradient)) {
  161.     bgBitmap.cGradientFrom = GetColor();
  162.     bgBitmap.cGradientTo = GetColor();
  163.  
  164.     bgBitmap.iType = MIL_GRADIENT;
  165.  
  166.     goto done;
  167.   }
  168.   if (!lstrcmpi(szTemp, szFillScreen)) {
  169.     bgBitmap.rPos.right = uScrWidth;
  170.     bgBitmap.rPos.bottom = uScrHeight;
  171.     popstring(szTemp);
  172.   }
  173.   else if (!lstrcmpi(szTemp, szTiled)) {
  174.     popstring(szTemp);
  175.   }
  176.   else {
  177.     uWndWidth = 0;
  178.     uWndHeight = 0;
  179.   }
  180.  
  181.   BITMAP bBitmap;
  182.  
  183.   bgBitmap.hBitmap = LoadBitmapFile(bgBitmap.rPos.right, bgBitmap.rPos.bottom, &bBitmap);
  184.   if (!bgBitmap.hBitmap)
  185.     return;
  186.  
  187.   if (!bgBitmap.rPos.right) {
  188.     bgBitmap.rPos.right = bBitmap.bmWidth;
  189.     bgBitmap.rPos.bottom = bBitmap.bmHeight;
  190.   }
  191.   if (!uWndWidth) {
  192.     uWndWidth = bBitmap.bmWidth;
  193.     uWndHeight = bBitmap.bmHeight;
  194.   }
  195.  
  196. done:
  197.  
  198.   bgBitmap.bReady = TRUE;
  199.  
  200.   LCS();
  201.  
  202.   if (hWndImage) {
  203.     SetWindowPos(
  204.       hWndImage,
  205.       hWndParent,
  206.       (uScrWidth-uWndWidth)/2,
  207.       (uScrHeight-uWndHeight)/2,
  208.       uWndWidth,
  209.       uWndHeight,
  210.       SWP_NOACTIVATE
  211.     );
  212.   }
  213.  
  214.   my_pushstring("success");
  215. }
  216.  
  217. NSISFunc(AddImage) {
  218.   ECS();
  219.  
  220.   myImageList *newImg = (myImageList *)GlobalAlloc(GPTR, sizeof(myImageList));
  221.   if (!newImg) {
  222.     my_pushstring("memory allocation error");
  223.     LCS();
  224.     return;
  225.   }
  226.  
  227.   newImg->iType = MIL_BITMAP;
  228.   newImg->cTransparent = -1;
  229.  
  230.   popstring(szTemp);
  231.   if (!lstrcmpi(szTemp, "/TRANSPARENT")) {
  232.     newImg->iType = MIL_TRANSPARENT_BITMAP;
  233.     newImg->cTransparent = GetColor();
  234.     popstring(szTemp);
  235.   }
  236.  
  237.   BITMAP bBitmap;
  238.  
  239.   newImg->hBitmap = LoadBitmapFile(0, 0, &bBitmap);
  240.   if (!newImg->hBitmap) {
  241.     GlobalFree(newImg);
  242.     return;
  243.   }
  244.  
  245.   GetXY(LPPOINT(&newImg->rPos));
  246.  
  247.   newImg->rPos.right = newImg->rPos.left + bBitmap.bmWidth;
  248.   newImg->rPos.bottom = newImg->rPos.top + bBitmap.bmHeight;
  249.  
  250.   myImageList *img = &bgBitmap;
  251.   while (img->next) img = img->next;
  252.   img->next = newImg;
  253.  
  254.   my_pushstring("success");
  255.  
  256.   LCS();
  257. }
  258.  
  259. NSISFunc(AddText) {
  260.   ECS();
  261.  
  262.   myImageList *newImg = (myImageList *)GlobalAlloc(GPTR, sizeof(myImageList));
  263.   if (!newImg) {
  264.     my_pushstring("memory allocation error");
  265.     LCS();
  266.     return;
  267.   }
  268.  
  269.   newImg->iType = MIL_TEXT;
  270.  
  271.   popstring(szTemp);
  272.   newImg->szText = (char *)GlobalAlloc(GPTR, lstrlen(szTemp)+1);
  273.   if (!newImg->szText) {
  274.     my_pushstring("memory allocation error");
  275.     GlobalFree(newImg);
  276.     LCS();
  277.     return;
  278.   }
  279.   lstrcpy(newImg->szText, szTemp);
  280.  
  281.   popstring(szTemp);
  282.   newImg->hFont = (HFONT)myatoi(szTemp);
  283.   newImg->cTextColor = GetColor();
  284.   
  285.   GetXY(LPPOINT(&newImg->rPos));
  286.   GetXY(LPPOINT(&newImg->rPos) + 1);
  287.  
  288.   myImageList *img = &bgBitmap;
  289.   while (img->next) img = img->next;
  290.   img->next = newImg;
  291.  
  292.   my_pushstring("success");
  293.  
  294.   LCS();
  295. }
  296.  
  297. NSISFunc(Redraw) {
  298.   RedrawWindow(hWndImage, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW);
  299.   ShowWindow(hWndImage, SW_SHOWNA);
  300. }
  301.  
  302. NSISFunc(Clear) {
  303.   ECS();
  304.  
  305.   myImageList *img = &bgBitmap;
  306.   while (img) {
  307.     switch (img->iType) {
  308.       case MIL_BITMAP:
  309.       case MIL_TRANSPARENT_BITMAP:
  310.         DeleteObject(img->hBitmap);
  311.         break;
  312.       case MIL_TEXT:
  313.         GlobalFree(img->szText);
  314.         break;
  315.     }
  316.  
  317.     myImageList *thisImg = img;
  318.  
  319.     img = img->next;
  320.     thisImg->next = NULL;
  321.  
  322.     if (thisImg != &bgBitmap)
  323.       GlobalFree(thisImg);
  324.   }
  325.  
  326.   bgBitmap.bReady = FALSE;
  327.  
  328.   LCS();
  329. }
  330.  
  331. NSISFunc(Destroy) {
  332.   bgBitmap.bReady = FALSE;
  333.   if (IsWindow(hwndParent))
  334.     SetWindowLong(hwndParent, GWL_WNDPROC, (long)oldProc);
  335.   SendMessage(hWndImage, WM_CLOSE, 0, 0);
  336.   hWndImage = 0;
  337.   Clear(0, 0, 0, 0);
  338.   UnregisterClass("NSISBGImage", g_hInstance);
  339. }
  340.  
  341. NSISFunc(Sound) {
  342.   char szLoop[] = {'/', 'L', 'O', 'O', 'P', 0};
  343.   char szWait[] = {'/', 'W', 'A', 'I', 'T', 0};
  344.   char szStop[] = {'/', 'S', 'T', 'O', 'P', 0};
  345.  
  346.   DWORD flags = SND_FILENAME | SND_NODEFAULT;
  347.   
  348.   g_stacktop = stacktop;
  349.   popstring(szTemp);
  350.   if (lstrcmpi(szTemp, szWait))
  351.     flags |= SND_ASYNC;
  352.   else
  353.     popstring(szTemp);
  354.   if (!lstrcmpi(szTemp, szLoop)) {
  355.     flags |= SND_LOOP;
  356.     popstring(szTemp);
  357.   }
  358.   PlaySound(lstrcmpi(szTemp, szStop) ? szTemp : 0, 0, flags);
  359. }
  360.  
  361. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  362.   HWND hwndParent = hWndParent;
  363.   HWND hwndImage = hWndImage;
  364.  
  365.   if (hwnd == hwndParent) {
  366.     if (message == WM_SIZE) {
  367.       ShowWindow(hwndImage, wParam == SIZE_MINIMIZED ? SW_HIDE : SW_SHOW);
  368.     }
  369.     if (message == WM_WINDOWPOSCHANGED) {
  370.       SetWindowPos(hwndImage, hwndParent, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
  371.     }
  372.     return CallWindowProc(
  373.       (long (__stdcall *)(HWND,unsigned int,unsigned int,long))oldProc,
  374.       hwnd,
  375.       message,
  376.       wParam,
  377.       lParam
  378.     );
  379.   }
  380.   switch (message) {
  381.     case WM_PAINT:
  382.     if (bgBitmap.bReady) {
  383.       ECS();
  384.  
  385.       PAINTSTRUCT ps;
  386.       HDC hdc = BeginPaint(hwnd, &ps);
  387.  
  388.       if (bgBitmap.iType == MIL_BITMAP) {
  389.         HDC cdc = CreateCompatibleDC(hdc);
  390.         SelectObject(cdc, bgBitmap.hBitmap);
  391.         for (unsigned int x = 0; x < uWndWidth; x += bgBitmap.rPos.right) {
  392.           for (unsigned int y = 0; y < uWndHeight; y += bgBitmap.rPos.bottom) {
  393.             BitBlt(hdc, x, y, bgBitmap.rPos.right, bgBitmap.rPos.bottom, cdc, 0, 0, SRCCOPY);
  394.           }
  395.         }
  396.         DeleteDC(cdc);
  397.       }
  398.       else {
  399.         int r = GetRValue(bgBitmap.cGradientFrom) << 10;
  400.         int g = GetGValue(bgBitmap.cGradientFrom) << 10;
  401.         int b = GetBValue(bgBitmap.cGradientFrom) << 10;
  402.         int dr = ((GetRValue(bgBitmap.cGradientTo) << 10) - r) / (int)uWndHeight * 4;
  403.         int dg = ((GetGValue(bgBitmap.cGradientTo) << 10) - g) / (int)uWndHeight * 4;
  404.         int db = ((GetBValue(bgBitmap.cGradientTo) << 10) - b) / (int)uWndHeight * 4;
  405.         RECT rect;
  406.         rect.left = 0;
  407.         rect.top = 0;
  408.         rect.right = uWndWidth;
  409.         rect.bottom = 4;
  410.         while (rect.top < (int)uWndHeight)
  411.         {
  412.           HBRUSH brush = CreateSolidBrush(RGB(r>>10,g>>10,b>>10));
  413.           FillRect(hdc, &rect, brush);
  414.           DeleteObject(brush);
  415.           rect.top+=4;
  416.           rect.bottom+=4;
  417.           r+=dr;
  418.           g+=dg;
  419.           b+=db;
  420.         }
  421.       }
  422.  
  423.       myImageList *img = bgBitmap.next;
  424.       while (img) {
  425.         if (img->iType == MIL_TEXT) {
  426.           SetBkMode(hdc, TRANSPARENT);
  427.  
  428.           SetTextColor(hdc, img->cTextColor);
  429.           SelectObject(hdc, img->hFont);
  430.           DrawText(hdc, img->szText, -1, &img->rPos, DT_TOP | DT_LEFT | DT_NOPREFIX | DT_WORDBREAK);
  431.         }
  432.         else if (img->iType == MIL_BITMAP) {
  433.           HDC cdc = CreateCompatibleDC(hdc);
  434.           SelectObject(cdc, img->hBitmap);
  435.           BitBlt(hdc, img->rPos.left, img->rPos.top, img->rPos.right - img->rPos.left, img->rPos.bottom - img->rPos.top, cdc, 0, 0, SRCCOPY);
  436.           DeleteDC(cdc);
  437.         }
  438.         else {
  439.           COLORREF   cColor;
  440.           HBITMAP    bmAndBack, bmAndObject, bmAndMem, bmSave;
  441.           HBITMAP    bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
  442.           HDC        hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
  443.           POINT      ptSize;
  444.  
  445.           HBITMAP hBitmap = img->hBitmap;
  446.  
  447.           hdcTemp = CreateCompatibleDC(hdc);
  448.           SelectObject(hdcTemp, hBitmap);   // Select the bitmap
  449.  
  450.           ptSize.x = img->rPos.right - img->rPos.left;
  451.           ptSize.y = img->rPos.bottom - img->rPos.top;
  452.           DPtoLP(hdcTemp, &ptSize, 1);  // Convert from device to logical points
  453.  
  454.           // Create some DCs to hold temporary data.
  455.           hdcBack   = CreateCompatibleDC(hdc);
  456.           hdcObject = CreateCompatibleDC(hdc);
  457.           hdcMem    = CreateCompatibleDC(hdc);
  458.           hdcSave   = CreateCompatibleDC(hdc);
  459.  
  460.           // Create a bitmap for each DC. DCs are required for a number of
  461.           // GDI functions.
  462.  
  463.           // Monochrome DC
  464.           bmAndBack   = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
  465.  
  466.           // Monochrome DC
  467.           bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
  468.  
  469.           bmAndMem    = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
  470.           bmSave      = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
  471.  
  472.           // Each DC must select a bitmap object to store pixel data.
  473.           bmBackOld   = (HBITMAP)SelectObject(hdcBack, bmAndBack);
  474.           bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);
  475.           bmMemOld    = (HBITMAP)SelectObject(hdcMem, bmAndMem);
  476.           bmSaveOld   = (HBITMAP)SelectObject(hdcSave, bmSave);
  477.  
  478.           // Set proper mapping mode.
  479.           SetMapMode(hdcTemp, GetMapMode(hdc));
  480.  
  481.           // Save the bitmap sent here, because it will be overwritten.
  482.           BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
  483.  
  484.           // Set the background color of the source DC to the color.
  485.           // contained in the parts of the bitmap that should be transparent
  486.           cColor = SetBkColor(hdcTemp, img->cTransparent);
  487.  
  488.           // Create the object mask for the bitmap by performing a BitBlt
  489.           // from the source bitmap to a monochrome bitmap.
  490.           BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,
  491.               SRCCOPY);
  492.  
  493.           // Set the background color of the source DC back to the original
  494.           // color.
  495.           SetBkColor(hdcTemp, cColor);
  496.  
  497.           // Create the inverse of the object mask.
  498.           BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,
  499.               NOTSRCCOPY);
  500.  
  501.           // Copy the background of the main DC to the destination.
  502.           BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, img->rPos.left, img->rPos.top,
  503.               SRCCOPY);
  504.  
  505.           // Mask out the places where the bitmap will be placed.
  506.           BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
  507.  
  508.           // Mask out the transparent colored pixels on the bitmap.
  509.           BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
  510.  
  511.           // XOR the bitmap with the background on the destination DC.
  512.           BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
  513.  
  514.           // Copy the destination to the screen.
  515.           BitBlt(hdc, img->rPos.left, img->rPos.top, ptSize.x, ptSize.y, hdcMem, 0, 0,
  516.               SRCCOPY);
  517.  
  518.           // Place the original bitmap back into the bitmap sent here.
  519.           BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
  520.  
  521.           // Delete the memory bitmaps.
  522.           DeleteObject(SelectObject(hdcBack, bmBackOld));
  523.           DeleteObject(SelectObject(hdcObject, bmObjectOld));
  524.           DeleteObject(SelectObject(hdcMem, bmMemOld));
  525.           DeleteObject(SelectObject(hdcSave, bmSaveOld));
  526.  
  527.           // Delete the memory DCs.
  528.           DeleteDC(hdcMem);
  529.           DeleteDC(hdcBack);
  530.           DeleteDC(hdcObject);
  531.           DeleteDC(hdcSave);
  532.           DeleteDC(hdcTemp);
  533.         }
  534.         img = img->next;
  535.       }
  536.  
  537.       LCS();
  538.  
  539.       EndPaint(hwnd, &ps);
  540.     }
  541.     break;
  542.     case WM_WINDOWPOSCHANGING:
  543.       if (IsWindow(hwndParent))
  544.       {
  545.         LPWINDOWPOS wp = (LPWINDOWPOS) lParam;
  546.         wp->flags |= SWP_NOACTIVATE;
  547.         wp->hwndInsertAfter = hwndParent;
  548.       }
  549.       break;
  550.     case WM_CLOSE:
  551.       DestroyWindow(hwnd);
  552.     break;
  553.     default:
  554.       return DefWindowProc(hwnd, message, wParam, lParam);
  555.   }
  556.   return 0;
  557. }
  558.  
  559. HBITMAP __stdcall LoadBitmapFile(long right, long bottom, BITMAP *bBitmap)
  560. {
  561.   HBITMAP hBitmap = (HBITMAP)LoadImage(0, szTemp, IMAGE_BITMAP, right, bottom, LR_LOADFROMFILE);
  562.   if (!hBitmap || !GetObject(hBitmap, sizeof(BITMAP), (void *)bBitmap)) {
  563.     my_pushstring("can't load bitmap");
  564.     if (hBitmap)
  565.       DeleteObject(hBitmap);
  566.     LCS();
  567.     return 0;
  568.   }
  569.   return hBitmap;
  570. }
  571.  
  572. COLORREF GetColor() {
  573.   COLORREF cColor = 0;
  574.   popstring(szTemp);
  575.   cColor |= (BYTE) myatoi(szTemp);
  576.   popstring(szTemp);
  577.   cColor |= ((BYTE) myatoi(szTemp)) << 8;
  578.   popstring(szTemp);
  579.   cColor |= ((BYTE) myatoi(szTemp)) << 16;
  580.   return cColor;
  581. }
  582.  
  583. void __stdcall GetXY(LPPOINT lpPoint) {
  584.   popstring(szTemp);
  585.   int iPosTemp = myatoi(szTemp);
  586.   if (iPosTemp < 0) iPosTemp = iPosTemp + (int)uWndWidth;
  587.   lpPoint->x = (unsigned int)iPosTemp;
  588.  
  589.   popstring(szTemp);
  590.   iPosTemp = myatoi(szTemp);
  591.   if (iPosTemp < 0) iPosTemp = iPosTemp + (int)uWndHeight;
  592.   lpPoint->y = (unsigned int)iPosTemp;
  593. }
  594.  
  595. int __stdcall myatoi(char *s)
  596. {
  597.   unsigned int v=0;
  598.   if (*s == '0' && (s[1] == 'x' || s[1] == 'X'))
  599.   {
  600.     s+=2;
  601.     for (;;)
  602.     {
  603.       int c=*s++;
  604.       if (c >= '0' && c <= '9') c-='0';
  605.       else if (c >= 'a' && c <= 'f') c-='a'-10;
  606.       else if (c >= 'A' && c <= 'F') c-='A'-10;
  607.       else break;
  608.       v<<=4;
  609.       v+=c;
  610.     }
  611.   }
  612.   else if (*s == '0' && s[1] <= '7' && s[1] >= '0')
  613.   {
  614.     s++;
  615.     for (;;)
  616.     {
  617.       int c=*s++;
  618.       if (c >= '0' && c <= '7') c-='0';
  619.       else break;
  620.       v<<=3;
  621.       v+=c;
  622.     }
  623.   }
  624.   else
  625.   {
  626.     int sign=0;
  627.     if (*s == '-') { s++; sign++; }
  628.     for (;;)
  629.     {
  630.       int c=*s++ - '0';
  631.       if (c < 0 || c > 9) break;
  632.       v*=10;
  633.       v+=c;
  634.     }
  635.     if (sign) return -(int) v;
  636.   }
  637.   return (int)v;
  638. }
  639.  
  640. BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
  641.   g_hInstance=hInst;
  642.   switch (ul_reason_for_call) {
  643.     case DLL_PROCESS_ATTACH:
  644.       InitializeCriticalSection(&CriticalSection);
  645.       break;
  646.     case DLL_PROCESS_DETACH:
  647.       DeleteCriticalSection(&CriticalSection);
  648.       break;
  649.   }
  650.   return TRUE;
  651. }