utils.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:10k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * utils.cpp: ActiveX control for VLC
  3.  *****************************************************************************
  4.  * Copyright (C) 2005 the VideoLAN team
  5.  *
  6.  * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  21.  *****************************************************************************/
  22. #include "utils.h"
  23. #include <wchar.h>
  24. #include <wctype.h>
  25. /*
  26. ** conversion facilities
  27. */
  28. using namespace std;
  29. char *CStrFromWSTR(UINT codePage, LPCWSTR wstr, UINT len)
  30. {
  31.     if( len > 0 )
  32.     {
  33.         size_t mblen = WideCharToMultiByte(codePage,
  34.                 0, wstr, len, NULL, 0, NULL, NULL);
  35.         if( mblen > 0 )
  36.         {
  37.             char *buffer = (char *)CoTaskMemAlloc(mblen+1);
  38.             ZeroMemory(buffer, mblen+1);
  39.             if( WideCharToMultiByte(codePage, 0, wstr, len, buffer, mblen, NULL, NULL) )
  40.             {
  41.                 buffer[mblen] = '';
  42.                 return buffer;
  43.             }
  44.         }
  45.     }
  46.     return NULL;
  47. };
  48. char *CStrFromBSTR(UINT codePage, BSTR bstr)
  49. {
  50.     return CStrFromWSTR(codePage, bstr, SysStringLen(bstr));
  51. };
  52. BSTR BSTRFromCStr(UINT codePage, LPCSTR s)
  53. {
  54.     int wideLen = MultiByteToWideChar(codePage, 0, s, -1, NULL, 0);
  55.     if( wideLen > 0 )
  56.     {
  57.         WCHAR* wideStr = (WCHAR*)CoTaskMemAlloc(wideLen*sizeof(WCHAR));
  58.         if( NULL != wideStr )
  59.         {
  60.             BSTR bstr;
  61.             ZeroMemory(wideStr, wideLen*sizeof(WCHAR));
  62.             MultiByteToWideChar(codePage, 0, s, -1, wideStr, wideLen);
  63.             bstr = SysAllocStringLen(wideStr, wideLen-1);
  64.             CoTaskMemFree(wideStr);
  65.             return bstr;
  66.         }
  67.     }
  68.     return NULL;
  69. };
  70. /*
  71. **  properties
  72. */
  73. HRESULT GetObjectProperty(LPUNKNOWN object, DISPID dispID, VARIANT& v)
  74. {
  75.     IDispatch *pDisp;
  76.     HRESULT hr = object->QueryInterface(IID_IDispatch, (LPVOID *)&pDisp);
  77.     if( SUCCEEDED(hr) )
  78.     {
  79.         DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
  80.         VARIANT vres;
  81.         VariantInit(&vres);
  82.         hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT,
  83.                 DISPATCH_PROPERTYGET, &dispparamsNoArgs, &vres, NULL, NULL);
  84.         if( SUCCEEDED(hr) )
  85.         {
  86.             if( V_VT(&v) != V_VT(&vres) )
  87.             {
  88.                 hr = VariantChangeType(&v, &vres, 0, V_VT(&v));
  89.                 VariantClear(&vres);
  90.             }
  91.             else
  92.             {
  93.                 v = vres;
  94.             }
  95.         }
  96.         pDisp->Release();
  97.     }
  98.     return hr;
  99. };
  100. HDC CreateDevDC(DVTARGETDEVICE *ptd)
  101. {
  102.     HDC hdc=NULL;
  103.     if( NULL == ptd )
  104.     {
  105.         hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
  106.     }
  107.     else
  108.     {
  109.         LPDEVNAMES lpDevNames;
  110.         LPDEVMODE lpDevMode;
  111.         LPTSTR lpszDriverName;
  112.         LPTSTR lpszDeviceName;
  113.         LPTSTR lpszPortName;
  114.         lpDevNames = (LPDEVNAMES) ptd; // offset for size field
  115.         if (ptd->tdExtDevmodeOffset == 0)
  116.         {
  117.             lpDevMode = NULL;
  118.         }
  119.         else
  120.         {
  121.             lpDevMode  = (LPDEVMODE) ((LPTSTR)ptd + ptd->tdExtDevmodeOffset);
  122.         }
  123.         lpszDriverName = (LPTSTR) lpDevNames + ptd->tdDriverNameOffset;
  124.         lpszDeviceName = (LPTSTR) lpDevNames + ptd->tdDeviceNameOffset;
  125.         lpszPortName   = (LPTSTR) lpDevNames + ptd->tdPortNameOffset;
  126.         hdc = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, lpDevMode);
  127.     }
  128.         return hdc;
  129. };
  130. #define HIMETRIC_PER_INCH 2540
  131. void DPFromHimetric(HDC hdc, LPPOINT pt, int count)
  132. {
  133.     LONG lpX = GetDeviceCaps(hdc, LOGPIXELSX);
  134.     LONG lpY = GetDeviceCaps(hdc, LOGPIXELSY);
  135.     while( count-- )
  136.     {
  137.         pt->x = pt->x*lpX/HIMETRIC_PER_INCH;
  138.         pt->y = pt->y*lpY/HIMETRIC_PER_INCH;
  139.         ++pt;
  140.     }
  141. };
  142. void HimetricFromDP(HDC hdc, LPPOINT pt, int count)
  143. {
  144.     LONG lpX = GetDeviceCaps(hdc, LOGPIXELSX);
  145.     LONG lpY = GetDeviceCaps(hdc, LOGPIXELSY);
  146.     while( count-- )
  147.     {
  148.         pt->x = pt->x*HIMETRIC_PER_INCH/lpX;
  149.         pt->y = pt->y*HIMETRIC_PER_INCH/lpY;
  150.         ++pt;
  151.     }
  152. };
  153. LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url)
  154. {
  155.     if( NULL != url )
  156.     {
  157.         // check whether URL is already absolute
  158.         const wchar_t *end=wcschr(url, L':');
  159.         if( (NULL != end) && (end != url) )
  160.         {
  161.             // validate protocol header
  162.             const wchar_t *start = url;
  163.             wchar_t c = *start;
  164.             if( iswalpha(c) )
  165.             {
  166.                 ++start;
  167.                 while( start != end )
  168.                 {
  169.                     c = *start;
  170.                     if( ! (iswalnum(c)
  171.                        || (L'-' == c)
  172.                        || (L'+' == c)
  173.                        || (L'.' == c)
  174.                        || (L'/' == c)) ) /* VLC uses / to allow user to specify a demuxer */
  175.                         // not valid protocol header, assume relative URL
  176.                         goto relativeurl;
  177.                     ++start;
  178.                 }
  179.                 /* we have a protocol header, therefore URL is absolute */
  180.                 UINT len = wcslen(url);
  181.                 wchar_t *href = (LPWSTR)CoTaskMemAlloc((len+1)*sizeof(wchar_t));
  182.                 if( href )
  183.                 {
  184.                     memcpy(href, url, len*sizeof(wchar_t));
  185.                     href[len] = L'';
  186.                 }
  187.                 return href;
  188.             }
  189.         }
  190. relativeurl:
  191.         if( baseUrl )
  192.         {
  193.             size_t baseLen = wcslen(baseUrl);
  194.             wchar_t *href = (LPWSTR)CoTaskMemAlloc((baseLen+wcslen(url)+1)*sizeof(wchar_t));
  195.             if( href )
  196.             {
  197.                 /* prepend base URL */
  198.                 wcscpy(href, baseUrl);
  199.                 /*
  200.                 ** relative url could be empty,
  201.                 ** in which case return base URL
  202.                 */
  203.                 if( L'' == *url )
  204.                     return href;
  205.                 /*
  206.                 ** locate pathname part of base URL
  207.                 */
  208.                 /* skip over protocol part  */
  209.                 wchar_t *pathstart = wcschr(href, L':');
  210.                 wchar_t *pathend;
  211.                 if( pathstart )
  212.                 {
  213.                     if( L'/' == *(++pathstart) )
  214.                     {
  215.                         if( L'/' == *(++pathstart) )
  216.                         {
  217.                             ++pathstart;
  218.                         }
  219.                     }
  220.                     /* skip over host part */
  221.                     pathstart = wcschr(pathstart, L'/');
  222.                     pathend = href+baseLen;
  223.                     if( ! pathstart )
  224.                     {
  225.                         // no path, add a / past end of url (over '')
  226.                         pathstart = pathend;
  227.                         *pathstart = L'/';
  228.                     }
  229.                 }
  230.                 else
  231.                 {
  232.                     /* baseURL is just a UNIX file path */
  233.                     if( L'/' != *href )
  234.                     {
  235.                         /* baseURL is not an absolute path */
  236.                         return NULL;
  237.                     }
  238.                     pathstart = href;
  239.                     pathend = href+baseLen;
  240.                 }
  241.                 /* relative URL made of an absolute path ? */
  242.                 if( L'/' == *url )
  243.                 {
  244.                     /* replace path completely */
  245.                     wcscpy(pathstart, url);
  246.                     return href;
  247.                 }
  248.                 /* find last path component and replace it */
  249.                 while( L'/' != *pathend )
  250.                     --pathend;
  251.                 /*
  252.                 ** if relative url path starts with one or more './' or '../',
  253.                 ** factor them out of href so that we return a
  254.                 ** normalized URL
  255.                 */
  256.                 while( pathend > pathstart )
  257.                 {
  258.                     const wchar_t *p = url;
  259.                     if( L'.' != *p )
  260.                         break;
  261.                     ++p;
  262.                     if( L'' == *p  )
  263.                     {
  264.                         /* relative url is just '.' */
  265.                         url = p;
  266.                         break;
  267.                     }
  268.                     if( L'/' == *p  )
  269.                     {
  270.                         /* relative url starts with './' */
  271.                         url = ++p;
  272.                         continue;
  273.                     }
  274.                     if( L'.' != *p )
  275.                         break;
  276.                     ++p;
  277.                     if( L'' == *p )
  278.                     {
  279.                         /* relative url is '..' */
  280.                     }
  281.                     else
  282.                     {
  283.                         if( L'/' != *p )
  284.                             break;
  285.                         /* relative url starts with '../' */
  286.                         ++p;
  287.                     }
  288.                     url = p;
  289.                     do
  290.                     {
  291.                         --pathend;
  292.                     }
  293.                     while( L'/' != *pathend );
  294.                 }
  295.                 /* skip over '/' separator */
  296.                 ++pathend;
  297.                 /* concatenate remaining base URL and relative URL */
  298.                 wcscpy(pathend, url);
  299.             }
  300.             return href;
  301.         }
  302.     }
  303.     return NULL;
  304. }