/******************************************************************************** Copyright (C) 2012 Hugh Bailey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ********************************************************************************/ #include "OBSAPI.h" APIInterface *API = NULL; void ApplyRTL(HWND hwnd, bool bRTL) { if (!bRTL) return; TCHAR controlClassName[128]; GetClassName(hwnd, controlClassName, 128); if (scmpi(controlClassName, L"Static") == 0) { LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE); style ^= SS_RIGHT; SetWindowLongPtr(hwnd, GWL_STYLE, style); } LONG_PTR styles = GetWindowLongPtr(hwnd, GWL_EXSTYLE); styles ^= WS_EX_RIGHT; styles |= WS_EX_RTLREADING; SetWindowLongPtr(hwnd, GWL_EXSTYLE, styles); } void LocalizeWindow(HWND hwnd, LocaleStringLookup *lookup) { if(!lookup) lookup = locale; bool bRTL = LocaleIsRTL(lookup); int textLen = (int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); String strText; strText.SetLength(textLen); GetWindowText(hwnd, strText, textLen+1); if(strText.IsValid() && lookup->HasLookup(strText)) SetWindowText(hwnd, lookup->LookupString(strText)); //------------------------------- RECT rect = { 0 }; GetClientRect(hwnd, &rect); HWND hwndChild = GetWindow(hwnd, GW_CHILD); while(hwndChild) { int textLen = (int)SendMessage(hwndChild, WM_GETTEXTLENGTH, 0, 0); strText.SetLength(textLen); GetWindowText(hwndChild, strText, textLen+1); if(strText.IsValid()) { if(strText[0] == '.') SetWindowText(hwndChild, strText.Array()+1); else { if(strText.IsValid() && lookup->HasLookup(strText)) SetWindowText(hwndChild, lookup->LookupString(strText)); } } hwndChild = GetNextWindow(hwndChild, GW_HWNDNEXT); } }; void LocalizeMenu(HMENU hMenu, LocaleStringLookup *lookup) { if(!lookup) lookup = locale; int itemCount = GetMenuItemCount(hMenu); if(itemCount == -1) return; bool bRTL = LocaleIsRTL(lookup); for(int i=0; iHasLookup(strLookup)) strName = strLookup; else strName = lookup->LookupString(strLookup); mii.fMask = MIIM_STRING|MIIM_FTYPE; mii.dwTypeData = strName.Array(); SetMenuItemInfo(hMenu, i, TRUE, &mii); if(hSubMenu) LocalizeMenu(hSubMenu); } } int OBSMessageBox(HWND hwnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT flags) { if (LocaleIsRTL()) flags |= MB_RTLREADING | MB_RIGHT; return MessageBox(hwnd, lpText, lpCaption, flags); } INT_PTR OBSDialogBox(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) { if (!LocaleIsRTL()) return DialogBoxParam(hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam); HRSRC dlg = FindResource(hInstance, lpTemplateName, RT_DIALOG); HGLOBAL rsc = LoadResource(hInstance, dlg); List tmpl; tmpl.InsertArray(0, (BYTE const*)LockResource(rsc), SizeofResource(hInstance, dlg)); *(DWORD*)&tmpl[sizeof WORD * 2 + sizeof DWORD] |= WS_EX_LAYOUTRTL; return DialogBoxIndirectParam(hInstance, (LPCDLGTEMPLATE)&tmpl[0], hWndParent, lpDialogFunc, dwInitParam); } HWND OBSCreateDialog(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) { if (!LocaleIsRTL()) return CreateDialogParam(hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam); HRSRC dlg = FindResource(hInstance, lpTemplateName, RT_DIALOG); HGLOBAL rsc = LoadResource(hInstance, dlg); List tmpl; tmpl.InsertArray(0, (BYTE const*)LockResource(rsc), SizeofResource(hInstance, dlg)); *(DWORD*)&tmpl[sizeof WORD * 2 + sizeof DWORD] |= WS_EX_LAYOUTRTL; return CreateDialogIndirectParam(hInstance, (LPCDLGTEMPLATE)&tmpl[0], hWndParent, lpDialogFunc, dwInitParam); } String GetLBText(HWND hwndList, UINT id) { UINT curSel = (id != LB_ERR) ? id : (UINT)SendMessage(hwndList, LB_GETCURSEL, 0, 0); if(curSel == LB_ERR) return String(); String strText; strText.SetLength((UINT)SendMessage(hwndList, LB_GETTEXTLEN, curSel, 0)); if(strText.Length()) SendMessage(hwndList, LB_GETTEXT, curSel, (LPARAM)strText.Array()); return strText; } String GetLVText(HWND hwndList, UINT id) { String strText; strText.SetLength(256); ListView_GetItemText(hwndList, id, 0, (LPWSTR)strText.Array(), 256); return strText; } String GetCBText(HWND hwndCombo, UINT id) { UINT curSel = (id != CB_ERR) ? id : (UINT)SendMessage(hwndCombo, CB_GETCURSEL, 0, 0); if(curSel == CB_ERR) return String(); String strText; strText.SetLength((UINT)SendMessage(hwndCombo, CB_GETLBTEXTLEN, curSel, 0)); if(strText.Length()) SendMessage(hwndCombo, CB_GETLBTEXT, curSel, (LPARAM)strText.Array()); return strText; } String GetEditText(HWND hwndEdit) { String strText; strText.SetLength((UINT)SendMessage(hwndEdit, WM_GETTEXTLENGTH, 0, 0)); if(strText.Length()) SendMessage(hwndEdit, WM_GETTEXT, strText.Length()+1, (LPARAM)strText.Array()); return strText; } static LPBYTE GetBitmapData(HBITMAP hBmp, BITMAP &bmp) { if (!hBmp) return NULL; if (GetObject(hBmp, sizeof(bmp), &bmp) != 0) { UINT bitmapDataSize = bmp.bmHeight*bmp.bmWidth*bmp.bmBitsPixel; bitmapDataSize >>= 3; LPBYTE lpBitmapData = (LPBYTE)Allocate(bitmapDataSize); GetBitmapBits(hBmp, bitmapDataSize, lpBitmapData); return lpBitmapData; } return NULL; } static inline BYTE BitToAlpha(LPBYTE lp1BitTex, int pixel, bool bInvert) { BYTE pixelByte = lp1BitTex[pixel/8]; BYTE pixelVal = pixelByte >> (7-(pixel%8)) & 1; if (bInvert) return pixelVal ? 0xFF : 0; else return pixelVal ? 0 : 0xFF; } LPBYTE GetCursorData(HICON hIcon, ICONINFO &ii, UINT &width, UINT &height) { BITMAP bmpColor, bmpMask; LPBYTE lpBitmapData = NULL, lpMaskData = NULL; if (lpBitmapData = GetBitmapData(ii.hbmColor, bmpColor)) { if (bmpColor.bmBitsPixel < 32) { Free(lpBitmapData); return NULL; } if (lpMaskData = GetBitmapData(ii.hbmMask, bmpMask)) { int pixels = bmpColor.bmHeight*bmpColor.bmWidth; bool bHasAlpha = false; //god-awful horrible hack to detect 24bit cursor for (int i=0; i 1.0f) val = 1.0f; destTemp[i] = val; } } } BOOL CALLBACK DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { #if defined _M_X64 && _MSC_VER == 1800 //workaround AVX2 bug in VS2013, http://connect.microsoft.com/VisualStudio/feedback/details/811093 _set_FMA3_enable(0); #endif } return TRUE; }