Misc.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476
  1. #include "stdafx.h"
  2. #include "CP_Main.h"
  3. #include "Misc.h"
  4. #include "OptionsSheet.h"
  5. #include "shared/TextConvert.h"
  6. #include "AlphaBlend.h"
  7. #include "Tlhelp32.h"
  8. #include <Wininet.h>
  9. #include "sqlite\utext.h"
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include "Path.h"
  13. CString GetIPAddress()
  14. {
  15. WORD wVersionRequested;
  16. WSADATA wsaData;
  17. char name[255];
  18. CString IP;
  19. PHOSTENT hostinfo;
  20. wVersionRequested = MAKEWORD(2,0);
  21. if (WSAStartup(wVersionRequested, &wsaData)==0)
  22. {
  23. if(gethostname(name, sizeof(name))==0)
  24. {
  25. if((hostinfo=gethostbyname(name)) != NULL)
  26. {
  27. IP = inet_ntoa(*(struct in_addr*)* hostinfo->h_addr_list);
  28. }
  29. }
  30. WSACleanup();
  31. }
  32. IP.MakeUpper();
  33. return IP;
  34. }
  35. CString GetComputerName()
  36. {
  37. TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH+1] = _T("");
  38. DWORD Size=MAX_COMPUTERNAME_LENGTH+1;
  39. GetComputerName(ComputerName, &Size);
  40. CString cs(ComputerName);
  41. cs.MakeUpper();
  42. return cs;
  43. }
  44. void AppendToFile(const TCHAR* fn, const TCHAR* msg)
  45. {
  46. #ifdef _UNICODE
  47. FILE *file = _wfopen(fn, _T("a"));
  48. #else
  49. FILE *file = fopen(fn, _T("a"));
  50. #endif
  51. ASSERT( file );
  52. if(file != NULL)
  53. {
  54. #ifdef _UNICODE
  55. fwprintf(file, _T("%s"), msg);
  56. #else
  57. fprintf(file, _T("%s"),msg);
  58. #endif
  59. fclose(file);
  60. }
  61. }
  62. void log(const TCHAR* msg, bool bFromSendRecieve, CString csFile, long lLine)
  63. {
  64. ASSERT(AfxIsValidString(msg));
  65. SYSTEMTIME st;
  66. GetLocalTime(&st);
  67. CString csText;
  68. csText.Format(_T("[%d/%d/%d %02d:%02d:%02d.%03d - "), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
  69. CString csFileLine;
  70. csFile = GetFileName(csFile);
  71. csFileLine.Format(_T("%s %d] "), csFile, lLine);
  72. csText += csFileLine;
  73. csText += msg;
  74. csText += "\n";
  75. #ifndef _DEBUG
  76. if(CGetSetOptions::m_bOutputDebugString)
  77. #endif
  78. {
  79. OutputDebugString(csText);
  80. }
  81. #ifndef _DEBUG
  82. if(!bFromSendRecieve)
  83. {
  84. if(!g_Opt.m_bEnableDebugLogging)
  85. return;
  86. }
  87. #endif
  88. CString csExeFile = CGetSetOptions::GetPath(PATH_LOG_FILE);
  89. csExeFile += "Ditto.log";
  90. AppendToFile(csExeFile, csText);
  91. }
  92. void logsendrecieveinfo(CString cs, CString csFile, long lLine)
  93. {
  94. if(g_Opt.m_bLogSendReceiveErrors)
  95. log(cs, true, csFile, lLine);
  96. }
  97. CString GetErrorString( int err )
  98. {
  99. CString str;
  100. LPVOID lpMsgBuf;
  101. ::FormatMessage(
  102. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  103. NULL,
  104. err,
  105. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  106. (LPTSTR) &lpMsgBuf,
  107. 0,
  108. NULL
  109. );
  110. str = (LPCTSTR) lpMsgBuf;
  111. // Display the string.
  112. // ::MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
  113. ::LocalFree( lpMsgBuf );
  114. return str;
  115. }
  116. int g_funnyGetTickCountAdjustment = -1;
  117. double IdleSeconds()
  118. {
  119. LASTINPUTINFO info;
  120. info.cbSize = sizeof(info);
  121. GetLastInputInfo(&info);
  122. DWORD currentTick = GetTickCount();
  123. if(g_funnyGetTickCountAdjustment == -1)
  124. {
  125. if(currentTick < info.dwTime)
  126. {
  127. g_funnyGetTickCountAdjustment = 1;
  128. }
  129. else
  130. {
  131. g_funnyGetTickCountAdjustment = 0;
  132. }
  133. }
  134. if(g_funnyGetTickCountAdjustment == 1 || g_funnyGetTickCountAdjustment == 2)
  135. {
  136. //Output message the first time
  137. if(g_funnyGetTickCountAdjustment == 1)
  138. {
  139. Log(StrF(_T("Adjusting time of get tickcount by: %d, on startup we found GetTickCount to be less than last input"), CGetSetOptions::GetFunnyTickCountAdjustment()));
  140. g_funnyGetTickCountAdjustment = 2;
  141. }
  142. currentTick += CGetSetOptions::GetFunnyTickCountAdjustment();
  143. }
  144. double idleSeconds = (currentTick - info.dwTime)/1000.0;
  145. return idleSeconds;
  146. }
  147. CString StrF(const TCHAR * pszFormat, ...)
  148. {
  149. ASSERT( AfxIsValidString( pszFormat ) );
  150. CString str;
  151. va_list argList;
  152. va_start( argList, pszFormat );
  153. str.FormatV( pszFormat, argList );
  154. va_end( argList );
  155. return str;
  156. }
  157. BYTE GetEscapeChar( BYTE ch )
  158. {
  159. switch(ch)
  160. {
  161. case '\'': return '\''; // Single quotation mark (') = 39 or 0x27
  162. case '\"': return '\"'; // Double quotation mark (") = 34 or 0x22
  163. case '?': return '\?'; // Question mark (?) = 63 or 0x3f
  164. case '\\': return '\\'; // Backslash (\) = 92 or 0x5c
  165. case 'a': return '\a'; // Alert (BEL) = 7
  166. case 'b': return '\b'; // Backspace (BS) = 8
  167. case 'f': return '\f'; // Formfeed (FF) = 12 or 0x0c
  168. case 'n': return '\n'; // Newline (NL or LF) = 10 or 0x0a
  169. case 'r': return '\r'; // Carriage Return (CR) = 13 or 0x0d
  170. case 't': return '\t'; // Horizontal tab (HT) = 9
  171. case 'v': return '\v'; // Vertical tab (VT) = 11 or 0x0b
  172. case '0': return '\0'; // Null character (NUL) = 0
  173. }
  174. return 0; // invalid
  175. }
  176. CString RemoveEscapes( const TCHAR* str )
  177. {
  178. ASSERT( str );
  179. CString ret;
  180. TCHAR* pSrc = (TCHAR*) str;
  181. TCHAR* pDest = ret.GetBuffer((int)STRLEN(pSrc));
  182. TCHAR* pStart = pDest;
  183. while( *pSrc != '\0' )
  184. {
  185. if( *pSrc == '\\' )
  186. {
  187. pSrc++;
  188. *pDest = GetEscapeChar((BYTE)pSrc );
  189. }
  190. else
  191. *pDest = *pSrc;
  192. pSrc++;
  193. pDest++;
  194. }
  195. ret.ReleaseBuffer((int)(pDest - pStart));
  196. return ret;
  197. }
  198. CString GetWndText( HWND hWnd )
  199. {
  200. CString text;
  201. if( !IsWindow(hWnd) )
  202. return "! NOT A VALID WINDOW !";
  203. CWnd* pWnd = CWnd::FromHandle(hWnd);
  204. pWnd->GetWindowText(text);
  205. return text;
  206. }
  207. bool IsAppWnd( HWND hWnd )
  208. {
  209. DWORD dwMyPID = ::GetCurrentProcessId();
  210. DWORD dwTestPID;
  211. ::GetWindowThreadProcessId( hWnd, &dwTestPID );
  212. return dwMyPID == dwTestPID;
  213. }
  214. /*----------------------------------------------------------------------------*\
  215. Global Memory Helper Functions
  216. \*----------------------------------------------------------------------------*/
  217. // make sure the given HGLOBAL is valid.
  218. BOOL IsValid(HGLOBAL hGlobal)
  219. {
  220. void* pvData = ::GlobalLock(hGlobal);
  221. ::GlobalUnlock(hGlobal);
  222. return (pvData != NULL);
  223. }
  224. // asserts if hDest isn't big enough
  225. void CopyToGlobalHP(HGLOBAL hDest, LPVOID pBuf, SIZE_T ulBufLen)
  226. {
  227. ASSERT(hDest && pBuf && ulBufLen);
  228. LPVOID pvData = GlobalLock(hDest);
  229. ASSERT(pvData);
  230. SIZE_T size = GlobalSize(hDest);
  231. ASSERT(size >= ulBufLen); // assert if hDest isn't big enough
  232. memcpy(pvData, pBuf, ulBufLen);
  233. GlobalUnlock(hDest);
  234. }
  235. void CopyToGlobalHH(HGLOBAL hDest, HGLOBAL hSource, SIZE_T ulBufLen)
  236. {
  237. ASSERT(hDest && hSource && ulBufLen);
  238. LPVOID pvData = GlobalLock(hSource);
  239. ASSERT(pvData );
  240. SIZE_T size = GlobalSize(hSource);
  241. ASSERT(size >= ulBufLen); // assert if hSource isn't big enough
  242. CopyToGlobalHP(hDest, pvData, ulBufLen);
  243. GlobalUnlock(hSource);
  244. }
  245. HGLOBAL NewGlobalP(LPVOID pBuf, SIZE_T nLen)
  246. {
  247. ASSERT(pBuf && nLen);
  248. HGLOBAL hDest = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, nLen);
  249. ASSERT(hDest );
  250. CopyToGlobalHP(hDest, pBuf, nLen);
  251. return hDest;
  252. }
  253. HGLOBAL NewGlobal(SIZE_T nLen)
  254. {
  255. ASSERT(nLen);
  256. HGLOBAL hDest = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, nLen);
  257. return hDest;
  258. }
  259. HGLOBAL NewGlobalH(HGLOBAL hSource, SIZE_T nLen)
  260. {
  261. ASSERT(hSource && nLen);
  262. LPVOID pvData = GlobalLock(hSource);
  263. HGLOBAL hDest = NewGlobalP(pvData, nLen);
  264. GlobalUnlock(hSource);
  265. return hDest;
  266. }
  267. int CompareGlobalHP(HGLOBAL hLeft, LPVOID pBuf, SIZE_T ulBufLen)
  268. {
  269. ASSERT(hLeft && pBuf && ulBufLen);
  270. LPVOID pvData = GlobalLock(hLeft);
  271. ASSERT(pvData);
  272. ASSERT(ulBufLen <= GlobalSize(hLeft));
  273. int result = memcmp(pvData, pBuf, ulBufLen);
  274. GlobalUnlock(hLeft);
  275. return result;
  276. }
  277. int CompareGlobalHH( HGLOBAL hLeft, HGLOBAL hRight, SIZE_T ulBufLen)
  278. {
  279. ASSERT(hLeft && hRight && ulBufLen);
  280. ASSERT(ulBufLen <= GlobalSize(hRight));
  281. LPVOID pvData = GlobalLock(hRight);
  282. ASSERT(pvData);
  283. int result = CompareGlobalHP(hLeft, pvData, ulBufLen);
  284. GlobalUnlock(hLeft);
  285. return result;
  286. }
  287. //Do not change these these are stored in the database
  288. CLIPFORMAT GetFormatID(LPCTSTR cbName)
  289. {
  290. if(STRCMP(cbName, _T("CF_TEXT")) == 0)
  291. return CF_TEXT;
  292. else if(STRCMP(cbName, _T("CF_METAFILEPICT")) == 0)
  293. return CF_METAFILEPICT;
  294. else if(STRCMP(cbName, _T("CF_SYLK")) == 0)
  295. return CF_SYLK;
  296. else if(STRCMP(cbName, _T("CF_DIF")) == 0)
  297. return CF_DIF;
  298. else if(STRCMP(cbName, _T("CF_TIFF")) == 0)
  299. return CF_TIFF;
  300. else if(STRCMP(cbName, _T("CF_OEMTEXT")) == 0)
  301. return CF_OEMTEXT;
  302. else if(STRCMP(cbName, _T("CF_DIB")) == 0)
  303. return CF_DIB;
  304. else if(STRCMP(cbName, _T("CF_PALETTE")) == 0)
  305. return CF_PALETTE;
  306. else if(STRCMP(cbName, _T("CF_PENDATA")) == 0)
  307. return CF_PENDATA;
  308. else if(STRCMP(cbName, _T("CF_RIFF")) == 0)
  309. return CF_RIFF;
  310. else if(STRCMP(cbName, _T("CF_WAVE")) == 0)
  311. return CF_WAVE;
  312. else if(STRCMP(cbName, _T("CF_UNICODETEXT")) == 0)
  313. return CF_UNICODETEXT;
  314. else if(STRCMP(cbName, _T("CF_ENHMETAFILE")) == 0)
  315. return CF_ENHMETAFILE;
  316. else if(STRCMP(cbName, _T("CF_HDROP")) == 0)
  317. return CF_HDROP;
  318. else if(STRCMP(cbName, _T("CF_LOCALE")) == 0)
  319. return CF_LOCALE;
  320. else if(STRCMP(cbName, _T("CF_OWNERDISPLAY")) == 0)
  321. return CF_OWNERDISPLAY;
  322. else if(STRCMP(cbName, _T("CF_DSPTEXT")) == 0)
  323. return CF_DSPTEXT;
  324. else if(STRCMP(cbName, _T("CF_DSPBITMAP")) == 0)
  325. return CF_DSPBITMAP;
  326. else if(STRCMP(cbName, _T("CF_DSPMETAFILEPICT")) == 0)
  327. return CF_DSPMETAFILEPICT;
  328. else if(STRCMP(cbName, _T("CF_DSPENHMETAFILE")) == 0)
  329. return CF_DSPENHMETAFILE;
  330. return ::RegisterClipboardFormat(cbName);
  331. }
  332. //Do not change these these are stored in the database
  333. CString GetFormatName(CLIPFORMAT cbType)
  334. {
  335. switch(cbType)
  336. {
  337. case CF_TEXT:
  338. return _T("CF_TEXT");
  339. case CF_BITMAP:
  340. return _T("CF_BITMAP");
  341. case CF_METAFILEPICT:
  342. return _T("CF_METAFILEPICT");
  343. case CF_SYLK:
  344. return _T("CF_SYLK");
  345. case CF_DIF:
  346. return _T("CF_DIF");
  347. case CF_TIFF:
  348. return _T("CF_TIFF");
  349. case CF_OEMTEXT:
  350. return _T("CF_OEMTEXT");
  351. case CF_DIB:
  352. return _T("CF_DIB");
  353. case CF_PALETTE:
  354. return _T("CF_PALETTE");
  355. case CF_PENDATA:
  356. return _T("CF_PENDATA");
  357. case CF_RIFF:
  358. return _T("CF_RIFF");
  359. case CF_WAVE:
  360. return _T("CF_WAVE");
  361. case CF_UNICODETEXT:
  362. return _T("CF_UNICODETEXT");
  363. case CF_ENHMETAFILE:
  364. return _T("CF_ENHMETAFILE");
  365. case CF_HDROP:
  366. return _T("CF_HDROP");
  367. case CF_LOCALE:
  368. return _T("CF_LOCALE");
  369. case CF_OWNERDISPLAY:
  370. return _T("CF_OWNERDISPLAY");
  371. case CF_DSPTEXT:
  372. return _T("CF_DSPTEXT");
  373. case CF_DSPBITMAP:
  374. return _T("CF_DSPBITMAP");
  375. case CF_DSPMETAFILEPICT:
  376. return _T("CF_DSPMETAFILEPICT");
  377. case CF_DSPENHMETAFILE:
  378. return _T("CF_DSPENHMETAFILE");
  379. default:
  380. //Not a default type get the name from the clipboard
  381. if (cbType != 0)
  382. {
  383. TCHAR szFormat[256];
  384. GetClipboardFormatName(cbType, szFormat, 256);
  385. return szFormat;
  386. }
  387. break;
  388. }
  389. return "ERROR";
  390. }
  391. CString GetFilePath(CString csFileName)
  392. {
  393. long lSlash = csFileName.ReverseFind('\\');
  394. if(lSlash > -1)
  395. {
  396. csFileName = csFileName.Left(lSlash + 1);
  397. }
  398. return csFileName;
  399. }
  400. CString GetFileName(CString csFileName)
  401. {
  402. long lSlash = csFileName.ReverseFind('\\');
  403. if(lSlash > -1)
  404. {
  405. csFileName = csFileName.Right(csFileName.GetLength() - lSlash - 1);
  406. }
  407. return csFileName;
  408. }
  409. /****************************************************************************************************
  410. BOOL CALLBACK MyMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
  411. ***************************************************************************************************/
  412. typedef struct
  413. {
  414. long lFlags; // Flags
  415. LPRECT pVirtualRect; // Ptr to rect that receives the results, or the src of the monitor search method
  416. int iMonitor; // Ndx to the mointor to look at, -1 for all, -or- result of the monitor search method
  417. int nMonitorCount; // Total number of monitors found, -1 for monitor search method
  418. } MONITOR_ENUM_PARAM;
  419. #define MONITOR_SEARCH_METOHD 0x00000001
  420. BOOL CALLBACK MyMonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
  421. {
  422. // Typecast param
  423. MONITOR_ENUM_PARAM* pParam = (MONITOR_ENUM_PARAM*)dwData;
  424. if(pParam)
  425. {
  426. // If a dest rect was passed
  427. if(pParam->pVirtualRect)
  428. {
  429. // If MONITOR_SEARCH_METOHD then we are being asked for the index of the monitor
  430. // that the rect falls inside of
  431. if(pParam->lFlags & MONITOR_SEARCH_METOHD)
  432. {
  433. if( (pParam->pVirtualRect->right < lprcMonitor->left) ||
  434. (pParam->pVirtualRect->left > lprcMonitor->right) ||
  435. (pParam->pVirtualRect->bottom < lprcMonitor->top) ||
  436. (pParam->pVirtualRect->top > lprcMonitor->bottom))
  437. {
  438. // Nothing
  439. }
  440. else
  441. {
  442. // This is the one
  443. pParam->iMonitor = pParam->nMonitorCount;
  444. // Stop the enumeration
  445. return FALSE;
  446. }
  447. }
  448. else
  449. {
  450. if(pParam->iMonitor == pParam->nMonitorCount)
  451. {
  452. *pParam->pVirtualRect = *lprcMonitor;
  453. }
  454. else
  455. if(pParam->iMonitor == -1)
  456. {
  457. pParam->pVirtualRect->left = min(pParam->pVirtualRect->left, lprcMonitor->left);
  458. pParam->pVirtualRect->top = min(pParam->pVirtualRect->top, lprcMonitor->top);
  459. pParam->pVirtualRect->right = max(pParam->pVirtualRect->right, lprcMonitor->right);
  460. pParam->pVirtualRect->bottom = max(pParam->pVirtualRect->bottom, lprcMonitor->bottom);
  461. }
  462. }
  463. }
  464. // Up the count if necessary
  465. pParam->nMonitorCount++;
  466. }
  467. return TRUE;
  468. }
  469. int GetScreenWidth(void)
  470. {
  471. OSVERSIONINFO OS_Version_Info;
  472. DWORD dwPlatform = 0;
  473. if(GetVersionEx(&OS_Version_Info) != 0)
  474. {
  475. dwPlatform = OS_Version_Info.dwPlatformId;
  476. }
  477. if(dwPlatform == VER_PLATFORM_WIN32_NT)
  478. {
  479. int width, height;
  480. width = GetSystemMetrics(SM_CXSCREEN);
  481. height = GetSystemMetrics(SM_CYSCREEN);
  482. switch(width)
  483. {
  484. default:
  485. case 640:
  486. case 800:
  487. case 1024:
  488. return(width);
  489. case 1280:
  490. if(height == 480)
  491. {
  492. return(width / 2);
  493. }
  494. return(width);
  495. case 1600:
  496. if(height == 600)
  497. {
  498. return(width / 2);
  499. }
  500. return(width);
  501. case 2048:
  502. if(height == 768)
  503. {
  504. return(width / 2);
  505. }
  506. return(width);
  507. }
  508. }
  509. else
  510. {
  511. return(GetSystemMetrics(SM_CXVIRTUALSCREEN));
  512. }
  513. }
  514. int GetScreenHeight(void)
  515. {
  516. OSVERSIONINFO OS_Version_Info;
  517. DWORD dwPlatform = 0;
  518. if(GetVersionEx(&OS_Version_Info) != 0)
  519. {
  520. dwPlatform = OS_Version_Info.dwPlatformId;
  521. }
  522. if(dwPlatform == VER_PLATFORM_WIN32_NT)
  523. {
  524. int width, height;
  525. width = GetSystemMetrics(SM_CXSCREEN);
  526. height = GetSystemMetrics(SM_CYSCREEN);
  527. switch(height)
  528. {
  529. default:
  530. case 480:
  531. case 600:
  532. case 768:
  533. return(height);
  534. case 960:
  535. if(width == 640)
  536. {
  537. return(height / 2);
  538. }
  539. return(height);
  540. case 1200:
  541. if(width == 800)
  542. {
  543. return(height / 2);
  544. }
  545. return(height);
  546. case 1536:
  547. if(width == 1024)
  548. {
  549. return(height / 2);
  550. }
  551. return(height);
  552. }
  553. }
  554. else
  555. {
  556. return(GetSystemMetrics(SM_CYVIRTUALSCREEN));
  557. }
  558. }
  559. int GetMonitorFromRect(LPRECT lpMonitorRect)
  560. {
  561. // Build up the param
  562. MONITOR_ENUM_PARAM EnumParam;
  563. ZeroMemory(&EnumParam, sizeof(EnumParam));
  564. EnumParam.lFlags = MONITOR_SEARCH_METOHD;
  565. EnumParam.pVirtualRect = lpMonitorRect;
  566. EnumParam.iMonitor = -1;
  567. // Enum Displays
  568. EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (LPARAM)&EnumParam);
  569. // Return the result
  570. return EnumParam.iMonitor;
  571. }
  572. void GetMonitorRect(int iMonitor, LPRECT lpDestRect)
  573. {
  574. // Build up the param
  575. MONITOR_ENUM_PARAM EnumParam;
  576. ZeroMemory(&EnumParam, sizeof(EnumParam));
  577. EnumParam.iMonitor = iMonitor;
  578. EnumParam.pVirtualRect = lpDestRect;
  579. // Zero out dest rect
  580. lpDestRect->bottom = lpDestRect->left = lpDestRect->right = lpDestRect->top = 0;
  581. // Enum Displays
  582. EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (LPARAM)&EnumParam);
  583. // If not successful, default to the screen dimentions
  584. if(lpDestRect->right == 0 || lpDestRect->bottom == 0)
  585. {
  586. lpDestRect->right = GetScreenWidth();
  587. lpDestRect->bottom = GetScreenHeight();
  588. }
  589. //adjust the rect for the taskbar
  590. APPBARDATA appBarData;
  591. appBarData.cbSize=sizeof(appBarData);
  592. if (SHAppBarMessage(ABM_GETTASKBARPOS, &appBarData))
  593. {
  594. switch(appBarData.uEdge)
  595. {
  596. case ABE_LEFT:
  597. lpDestRect->left += appBarData.rc.right - appBarData.rc.left;
  598. break;
  599. case ABE_RIGHT:
  600. lpDestRect->right -= appBarData.rc.right - appBarData.rc.left;
  601. break;
  602. case ABE_TOP:
  603. lpDestRect->top += appBarData.rc.bottom - appBarData.rc.top;
  604. break;
  605. case ABE_BOTTOM:
  606. lpDestRect->bottom -= appBarData.rc.bottom - appBarData.rc.top;
  607. break;
  608. }
  609. return;
  610. }
  611. }
  612. /*------------------------------------------------------------------*\
  613. ID based Globals
  614. \*------------------------------------------------------------------*/
  615. long NewGroupID(int parentID, CString text)
  616. {
  617. long lID=0;
  618. CTime time;
  619. time = CTime::GetCurrentTime();
  620. try
  621. {
  622. //sqlite doesn't like single quotes ' replace them with double ''
  623. if(text.IsEmpty())
  624. text = time.Format("NewGroup %y/%m/%d %H:%M:%S");
  625. text.Replace(_T("'"), _T("''"));
  626. CString cs;
  627. cs.Format(_T("insert into Main (lDate, mText, lDontAutoDelete, bIsGroup, lParentID, stickyClipOrder, stickyClipGroupOrder) values(%d, '%s', %d, 1, %d, -(2147483647), -(2147483647));"),
  628. (int)time.GetTime(),
  629. text,
  630. (int)time.GetTime(),
  631. parentID);
  632. theApp.m_db.execDML(cs);
  633. lID = (long)theApp.m_db.lastRowId();
  634. }
  635. CATCH_SQLITE_EXCEPTION_AND_RETURN(0)
  636. return lID;
  637. }
  638. BOOL DeleteAllIDs()
  639. {
  640. try
  641. {
  642. theApp.m_db.execDML(_T("DELETE FROM Data;"));
  643. theApp.m_db.execDML(_T("DELETE FROM Main;"));
  644. }
  645. CATCH_SQLITE_EXCEPTION
  646. return TRUE;
  647. }
  648. BOOL DeleteFormats(int parentID, ARRAY& formatIDs)
  649. {
  650. if(formatIDs.GetSize() <= 0)
  651. return TRUE;
  652. try
  653. {
  654. //Delete the requested data formats
  655. INT_PTR count = formatIDs.GetSize();
  656. for(int i = 0; i < count; i++)
  657. {
  658. int count = theApp.m_db.execDMLEx(_T("DELETE FROM Data WHERE lID = %d;"), formatIDs[i]);
  659. int k = 0;
  660. }
  661. CClip clip;
  662. if(clip.LoadFormats(parentID))
  663. {
  664. DWORD CRC = clip.GenerateCRC();
  665. //Update the main table with new size
  666. theApp.m_db.execDMLEx(_T("UPDATE Main SET CRC = %d WHERE lID = %d"), CRC, parentID);
  667. }
  668. }
  669. CATCH_SQLITE_EXCEPTION
  670. return TRUE;
  671. }
  672. CRect CenterRect(CRect startingRect)
  673. {
  674. CRect crMonitor;
  675. int nMonitor = GetMonitorFromRect(&startingRect);
  676. if(nMonitor < 0)
  677. {
  678. GetMonitorRect(0, crMonitor);
  679. }
  680. else
  681. {
  682. GetMonitorRect(nMonitor, crMonitor);
  683. }
  684. return CenterRectFromRect(startingRect, crMonitor);
  685. }
  686. CRect CenterRectFromRect(CRect startingRect, CRect outerRect)
  687. {
  688. CPoint center = outerRect.CenterPoint();
  689. CRect centerRect;
  690. centerRect.left = center.x - (startingRect.Width() / 2);
  691. centerRect.top = center.y - (startingRect.Height() / 2);
  692. centerRect.right = centerRect.left + startingRect.Width();
  693. centerRect.bottom = centerRect.top + startingRect.Height();
  694. return centerRect;
  695. }
  696. BOOL EnsureWindowVisible(CRect *pcrRect)
  697. {
  698. int nMonitor = GetMonitorFromRect(pcrRect);
  699. if(nMonitor < 0)
  700. {
  701. GetMonitorRect(0, pcrRect);
  702. pcrRect->right = pcrRect->left + 300;
  703. pcrRect->bottom = pcrRect->top + 300;
  704. return TRUE;
  705. }
  706. BOOL ret = FALSE;
  707. CRect crMonitor;
  708. GetMonitorRect(nMonitor, crMonitor);
  709. bool movedLeft = false;
  710. //Validate the left
  711. long lDiff = pcrRect->left - crMonitor.left;
  712. if(lDiff < 0)
  713. {
  714. pcrRect->left += abs(lDiff);
  715. pcrRect->right += abs(lDiff);
  716. ret = TRUE;
  717. movedLeft = true;
  718. }
  719. //Right side
  720. lDiff = pcrRect->right - crMonitor.right;
  721. if(lDiff > 0)
  722. {
  723. if(movedLeft == false)
  724. {
  725. pcrRect->left -= abs(lDiff);
  726. }
  727. pcrRect->right -= abs(lDiff);
  728. ret = TRUE;
  729. }
  730. bool movedTop = false;
  731. //Top
  732. lDiff = pcrRect->top - crMonitor.top;
  733. if(lDiff < 0)
  734. {
  735. pcrRect->top += abs(lDiff);
  736. pcrRect->bottom += abs(lDiff);
  737. ret = TRUE;
  738. movedTop = true;
  739. }
  740. //Bottom
  741. lDiff = pcrRect->bottom - crMonitor.bottom;
  742. if(lDiff > 0)
  743. {
  744. if(movedTop == false)
  745. {
  746. pcrRect->top -= abs(lDiff);
  747. }
  748. pcrRect->bottom -= abs(lDiff);
  749. ret = TRUE;
  750. }
  751. return ret;
  752. }
  753. __int64 GetLastWriteTime(const CString &csFile)
  754. {
  755. __int64 nLastWrite = 0;
  756. CFileFind finder;
  757. BOOL bResult = finder.FindFile(csFile);
  758. if (bResult)
  759. {
  760. finder.FindNextFile();
  761. FILETIME ft;
  762. finder.GetLastWriteTime(&ft);
  763. memcpy(&nLastWrite, &ft, sizeof(ft));
  764. }
  765. return nLastWrite;
  766. }
  767. typedef struct
  768. {
  769. DWORD ownerpid;
  770. DWORD childpid;
  771. } windowinfo;
  772. BOOL CALLBACK EnumChildWindowsCallback(HWND hWnd, LPARAM lp)
  773. {
  774. windowinfo* info = (windowinfo*)lp;
  775. DWORD pid = 0;
  776. GetWindowThreadProcessId(hWnd, &pid);
  777. if (pid != info->ownerpid)
  778. info->childpid = pid;
  779. return TRUE;
  780. }
  781. CString UWP_AppName(HWND active_window, DWORD ownerpid)
  782. {
  783. CString uwpAppName;
  784. windowinfo info = { 0 };
  785. info.ownerpid = ownerpid;
  786. info.childpid = info.ownerpid;
  787. EnumChildWindows(active_window, EnumChildWindowsCallback, (LPARAM)&info);
  788. HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.childpid);
  789. if (active_process != NULL)
  790. {
  791. WCHAR image_name[MAX_PATH] = { 0 };
  792. DWORD bufsize = MAX_PATH;
  793. QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
  794. CloseHandle(active_process);
  795. nsPath::CPath path(image_name);
  796. uwpAppName = path.GetName();
  797. }
  798. return uwpAppName;
  799. }
  800. CString GetProcessName(HWND hWnd, DWORD processId)
  801. {
  802. DWORD startTick = GetTickCount();
  803. CString strProcessName;
  804. DWORD Id = processId;
  805. if (Id == 0)
  806. {
  807. GetWindowThreadProcessId(hWnd, &Id);
  808. }
  809. HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, Id);
  810. if (active_process != NULL)
  811. {
  812. WCHAR image_name[MAX_PATH] = { 0 };
  813. DWORD bufsize = MAX_PATH;
  814. QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
  815. CloseHandle(active_process);
  816. nsPath::CPath path(image_name);
  817. strProcessName = path.GetName();
  818. }
  819. /*PROCESSENTRY32 processEntry = { 0 };
  820. HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  821. processEntry.dwSize = sizeof(PROCESSENTRY32);
  822. if (Process32First(hSnapShot, &processEntry))
  823. {
  824. do
  825. {
  826. if (processEntry.th32ProcessID == Id)
  827. {
  828. strProcessName = processEntry.szExeFile;
  829. break;
  830. }
  831. } while(Process32Next(hSnapShot, &processEntry));
  832. }
  833. CloseHandle(hSnapShot);*/
  834. //uwp apps are wrapped in another app called, if this has focus then try and find the child uwp process
  835. if (strProcessName == _T("ApplicationFrameHost.exe"))
  836. {
  837. strProcessName = UWP_AppName(hWnd, Id);
  838. }
  839. DWORD endTick = GetTickCount();
  840. DWORD diff = endTick - startTick;
  841. if(diff > 5)
  842. {
  843. Log(StrF(_T("GetProcessName Time (ms): %d"), endTick-startTick));
  844. }
  845. return strProcessName;
  846. }
  847. BOOL IsVista()
  848. {
  849. OSVERSIONINFO osver;
  850. osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  851. if (::GetVersionEx( &osver ) &&
  852. osver.dwPlatformId == VER_PLATFORM_WIN32_NT &&
  853. (osver.dwMajorVersion >= 6 ) )
  854. {
  855. return TRUE;
  856. }
  857. return FALSE;
  858. }
  859. bool IsRunningLimited()
  860. {
  861. LPCTSTR pszSubKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
  862. LPCTSTR pszValue = _T("EnableLUA");
  863. DWORD dwType = 0;
  864. DWORD dwValue = 0;
  865. DWORD dwValueSize = sizeof(DWORD);
  866. if(ERROR_SUCCESS != SHGetValue(HKEY_LOCAL_MACHINE, pszSubKey, pszValue, &dwType, &dwValue, &dwValueSize))
  867. {
  868. //failed to read the reg key, either it's not there or we don't have access to the registry
  869. //If we are vista then assume we don't have access and we are running as a limited app
  870. //otherwise we are xp and the reg key probably doesn't exist and we are not a limited running app
  871. if(IsVista())
  872. {
  873. OutputDebugString(_T("Ditto - Failed to read registry entry finding UAC, Running as limited application"));
  874. return true;
  875. }
  876. }
  877. if(dwValue == 1)
  878. {
  879. OutputDebugString(_T("Ditto - UAC ENABLED, Running as limited application"));
  880. return true;
  881. }
  882. OutputDebugString(_T("Ditto - Running as standard application"));
  883. return false;
  884. }
  885. void DeleteDittoTempFiles(BOOL checkFileLastAccess)
  886. {
  887. CString csDir = CGetSetOptions::GetPath(PATH_REMOTE_FILES);
  888. if (FileExists(csDir))
  889. {
  890. DeleteFolderFiles(csDir, checkFileLastAccess);
  891. }
  892. csDir = CGetSetOptions::GetPath(PATH_DRAG_FILES);
  893. if (FileExists(csDir))
  894. {
  895. DeleteFolderFiles(csDir, checkFileLastAccess);
  896. }
  897. csDir = CGetSetOptions::GetPath(PATH_CLIP_DIFF);
  898. if (FileExists(csDir))
  899. {
  900. DeleteFolderFiles(csDir, checkFileLastAccess);
  901. }
  902. }
  903. void DeleteFolderFiles(CString csDir, BOOL checkFileLastAccess)
  904. {
  905. if (csDir.Find(_T("\\ReceivedFiles\\")) == -1 && csDir.Find(_T("\\DragFiles\\")) == -1 && csDir.Find(_T("ClipCompare")) == -1)
  906. return;
  907. Log(StrF(_T("Deleting files in Folder %s Check Last Access %d"), csDir, checkFileLastAccess));
  908. FIX_CSTRING_PATH(csDir);
  909. CTime ctOld = CTime::GetCurrentTime();
  910. CTime ctFile;
  911. ctOld -= CTimeSpan(0, 0, 0, 1);
  912. CFileFind Find;
  913. CString csFindString;
  914. csFindString.Format(_T("%s*.*"), csDir);
  915. BOOL bFound = Find.FindFile(csFindString);
  916. while(bFound)
  917. {
  918. bFound = Find.FindNextFile();
  919. if(Find.IsDots())
  920. continue;
  921. if(Find.IsDirectory())
  922. {
  923. CString csDir(Find.GetFilePath());
  924. DeleteFolderFiles(csDir, checkFileLastAccess);
  925. RemoveDirectory(csDir);
  926. }
  927. if(checkFileLastAccess &&
  928. Find.GetLastAccessTime(ctFile))
  929. {
  930. //Delete the remote copied file if it hasn't been used for the last day
  931. if(ctFile < ctOld)
  932. {
  933. Log(StrF(_T("Deleting temp file %s"), Find.GetFilePath()));
  934. DeleteFile(Find.GetFilePath());
  935. }
  936. }
  937. else
  938. {
  939. Log(StrF(_T("Deleting temp file %s"), Find.GetFilePath()));
  940. DeleteFile(Find.GetFilePath());
  941. }
  942. }
  943. }
  944. __int64 FileSize(const TCHAR *fileName)
  945. {
  946. struct _stat64 buf;
  947. if (_wstat64((wchar_t const*)fileName, &buf) != 0)
  948. return -1; // error, could use errno to find out more
  949. return buf.st_size;
  950. }
  951. int FindNoCaseAndInsert(CString& mainStr, CString& findStr, CString preInsert, CString postInsert, int linesPerRow)
  952. {
  953. int replaceCount = 0;
  954. //Prevent infinite loop when user tries to replace nothing.
  955. if (findStr != "")
  956. {
  957. int oldLen = findStr.GetLength();
  958. int foundPos = 0;
  959. int startFindPos = 0;
  960. int newPos = 0;
  961. int insertedLength = 0;
  962. int firstFindPos = 0;
  963. //use icu::UnicodeString because it handles upper/lowercase characters for all languages, CSTring only hanldes ascii characters
  964. icu::UnicodeString mainLow(mainStr);
  965. mainLow.foldCase(U_FOLD_CASE_DEFAULT);
  966. icu::UnicodeString findLow(findStr);
  967. findLow.foldCase(U_FOLD_CASE_DEFAULT);
  968. int preLength = preInsert.GetLength();
  969. int postLength = postInsert.GetLength();
  970. int x = mainLow.indexOf(findLow, 0);
  971. while(TRUE)
  972. {
  973. foundPos = mainLow.indexOf(findLow, startFindPos);
  974. if (foundPos < 0)
  975. break;
  976. if (replaceCount == 0)
  977. {
  978. firstFindPos = foundPos + preLength;
  979. }
  980. newPos = foundPos + insertedLength;
  981. mainStr.Insert(newPos, preInsert);
  982. mainStr.Insert(newPos + preLength + oldLen, postInsert);
  983. startFindPos = foundPos + oldLen;
  984. insertedLength += preLength + postLength;
  985. replaceCount++;
  986. //safety check, make sure we don't look forever
  987. if (replaceCount > 100)
  988. break;
  989. }
  990. startFindPos = 0;
  991. int line = 0;
  992. int prevLinePos = 0;
  993. int prevPrevLinePos = 0;
  994. while (TRUE)
  995. {
  996. foundPos = mainStr.Find(_T("\n"), startFindPos);
  997. if (foundPos < 0)
  998. break;
  999. if (firstFindPos < foundPos)
  1000. {
  1001. if (line > linesPerRow - 1)
  1002. {
  1003. int lineStart = prevLinePos;
  1004. if (linesPerRow > 1)
  1005. {
  1006. lineStart = prevPrevLinePos;
  1007. }
  1008. mainStr = _T("... ") + mainStr.Mid(lineStart + 1);
  1009. }
  1010. break;
  1011. }
  1012. startFindPos = foundPos + 1;
  1013. prevPrevLinePos = prevLinePos;
  1014. prevLinePos = foundPos;
  1015. line++;
  1016. //safety check, make sure we don't look forever
  1017. if (line > 1000)
  1018. break;
  1019. }
  1020. if(replaceCount > 0)
  1021. {
  1022. //use unprintable characters so it doesn't find copied html to convert
  1023. mainStr.Replace(_T("\r\n"), _T("\x01\x05\x02"));
  1024. int l = mainStr.Replace(_T("\r"), _T("\x01\x05\x02"));
  1025. int m = mainStr.Replace(_T("\n"), _T("\x01\x05\x02"));
  1026. }
  1027. }
  1028. return replaceCount;
  1029. }
  1030. void OnInitMenuPopupEx(CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu, CWnd *pWnd)
  1031. {
  1032. ASSERT(pPopupMenu != NULL);
  1033. // Check the enabled state of various menu items.
  1034. CCmdUI state;
  1035. state.m_pMenu = pPopupMenu;
  1036. ASSERT(state.m_pOther == NULL);
  1037. ASSERT(state.m_pParentMenu == NULL);
  1038. // Determine if menu is popup in top-level menu and set m_pOther to
  1039. // it if so (m_pParentMenu == NULL indicates that it is secondary popup).
  1040. HMENU hParentMenu;
  1041. if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)
  1042. {
  1043. state.m_pParentMenu = pPopupMenu; // Parent == child for tracking popup.
  1044. }
  1045. else if ((hParentMenu = ::GetMenu(pWnd->m_hWnd)) != NULL)
  1046. {
  1047. CWnd* pParent = pWnd;
  1048. // Child windows don't have menus--need to go to the top!
  1049. if (pParent != NULL &&
  1050. (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
  1051. {
  1052. int nIndexMax = ::GetMenuItemCount(hParentMenu);
  1053. for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
  1054. {
  1055. if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)
  1056. {
  1057. // When popup is found, m_pParentMenu is containing menu.
  1058. state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
  1059. break;
  1060. }
  1061. }
  1062. }
  1063. }
  1064. state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
  1065. for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
  1066. state.m_nIndex++)
  1067. {
  1068. state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
  1069. if (state.m_nID == 0)
  1070. continue; // Menu separator or invalid cmd - ignore it.
  1071. ASSERT(state.m_pOther == NULL);
  1072. ASSERT(state.m_pMenu != NULL);
  1073. if (state.m_nID == (UINT)-1)
  1074. {
  1075. // Possibly a popup menu, route to first item of that popup.
  1076. state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
  1077. if (state.m_pSubMenu == NULL ||
  1078. (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
  1079. state.m_nID == (UINT)-1)
  1080. {
  1081. continue; // First item of popup can't be routed to.
  1082. }
  1083. state.DoUpdate(pWnd, TRUE); // Popups are never auto disabled.
  1084. }
  1085. else
  1086. {
  1087. // Normal menu item.
  1088. // Auto enable/disable if frame window has m_bAutoMenuEnable
  1089. // set and command is _not_ a system command.
  1090. state.m_pSubMenu = NULL;
  1091. state.DoUpdate(pWnd, FALSE);
  1092. }
  1093. // Adjust for menu deletions and additions.
  1094. UINT nCount = pPopupMenu->GetMenuItemCount();
  1095. if (nCount < state.m_nIndexMax)
  1096. {
  1097. state.m_nIndex -= (state.m_nIndexMax - nCount);
  1098. while (state.m_nIndex < nCount &&
  1099. pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
  1100. {
  1101. state.m_nIndex++;
  1102. }
  1103. }
  1104. state.m_nIndexMax = nCount;
  1105. }
  1106. }
  1107. CString InternetEncode(CString text)
  1108. {
  1109. CString ret = _T("");
  1110. LPTSTR lpOutputBuffer = new TCHAR[1];
  1111. DWORD dwSize = 1;
  1112. BOOL fRes = ::InternetCanonicalizeUrl(text, lpOutputBuffer, &dwSize, ICU_DECODE | ICU_NO_ENCODE);
  1113. DWORD dwError = ::GetLastError();
  1114. if (!fRes && dwError == ERROR_INSUFFICIENT_BUFFER)
  1115. {
  1116. delete lpOutputBuffer;
  1117. lpOutputBuffer = new TCHAR[dwSize];
  1118. fRes = ::InternetCanonicalizeUrl(text, lpOutputBuffer, &dwSize, ICU_DECODE | ICU_NO_ENCODE);
  1119. if (fRes)
  1120. {
  1121. ret = lpOutputBuffer;
  1122. //lpOutputBuffer has decoded url
  1123. }
  1124. else
  1125. {
  1126. //failed to decode
  1127. }
  1128. if (lpOutputBuffer != NULL)
  1129. {
  1130. delete [] lpOutputBuffer;
  1131. lpOutputBuffer = NULL;
  1132. }
  1133. }
  1134. else
  1135. {
  1136. //some other error OR the input string url is just 1 char and was successfully decoded
  1137. }
  1138. return ret;
  1139. }
  1140. void DeleteParamFromRTF(CStringA &test, CStringA find, bool searchForTrailingDigits)
  1141. {
  1142. int start = 0;
  1143. while (start >= 0)
  1144. {
  1145. start = test.Find(find, start);
  1146. if (start >= 0)
  1147. {
  1148. if (start > 0)
  1149. {
  1150. //leave it if the preceding character is \\, i was seeing the double slash if the actual text contained slash
  1151. if (test[start - 1] == '\\')
  1152. {
  1153. start++;
  1154. continue;
  1155. }
  1156. }
  1157. int end = -1;
  1158. int innerStart = start + find.GetLength();
  1159. if (searchForTrailingDigits)
  1160. {
  1161. for (int i = innerStart; i < test.GetLength(); i++)
  1162. {
  1163. if (isdigit(test[i]) == false)
  1164. {
  1165. end = i;
  1166. break;
  1167. }
  1168. }
  1169. }
  1170. else
  1171. {
  1172. end = innerStart;
  1173. }
  1174. if (end > 0)
  1175. {
  1176. if (searchForTrailingDigits == false ||
  1177. end != innerStart)
  1178. {
  1179. test.Delete(start, (end - start));
  1180. }
  1181. else
  1182. {
  1183. start++;
  1184. }
  1185. }
  1186. else
  1187. {
  1188. break;
  1189. }
  1190. }
  1191. }
  1192. }
  1193. bool RemoveRTFSection(CStringA &str, CStringA section)
  1194. {
  1195. bool removedSection = false;
  1196. int start2 = str.Find(section, 0);
  1197. int end2 = 0;
  1198. if (start2 >= 0)
  1199. {
  1200. int in = 0;
  1201. for (int pos = start2+1; pos < str.GetLength(); pos++)
  1202. {
  1203. if (str[pos] == '{')
  1204. {
  1205. in++;
  1206. }
  1207. if (str[pos] == '}')
  1208. {
  1209. if (in > 0)
  1210. {
  1211. in--;
  1212. }
  1213. else
  1214. {
  1215. end2 = pos;
  1216. break;
  1217. }
  1218. }
  1219. }
  1220. if (end2 > start2)
  1221. {
  1222. str.Delete(start2, (end2 - start2) + 1);
  1223. removedSection = true;
  1224. }
  1225. }
  1226. return removedSection;
  1227. }
  1228. CString NewGuidString()
  1229. {
  1230. CString guidString;
  1231. GUID guid;
  1232. CoCreateGuid(&guid);
  1233. guidString.Format(_T("%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX"),
  1234. guid.Data1, guid.Data2, guid.Data3,
  1235. guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
  1236. guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
  1237. return guidString;
  1238. }
  1239. CString FolderPath(int folderId)
  1240. {
  1241. CString folder = _T("");
  1242. if (folderId > 0)
  1243. {
  1244. try
  1245. {
  1246. CStringArray arr;
  1247. for (int i = 0; i < 100; i++)
  1248. {
  1249. CppSQLite3Query parent = theApp.m_db.execQueryEx(_T("SELECT lID, mText, lParentID FROM Main WHERE lID = %d"), folderId);
  1250. if (parent.eof() == false)
  1251. {
  1252. arr.Add(parent.getStringField(_T("mText")));
  1253. folderId = parent.getIntField(_T("lParentID"));
  1254. }
  1255. else
  1256. {
  1257. break;
  1258. }
  1259. }
  1260. folder = _T("Group Path: \\");
  1261. for (int folderPos = arr.GetCount() - 1; folderPos >= 0; folderPos--)
  1262. {
  1263. folder += _T("\\");
  1264. folder += arr[folderPos];
  1265. }
  1266. }
  1267. CATCH_SQLITE_EXCEPTION
  1268. }
  1269. return folder;
  1270. }