******************************************************************************** *!* ctl32_functions.prg ******************************************************************************** #Include ctl32.h If Not Sys(16) $ Upper(Set("Procedure")) Then Set Procedure To Sys(16) Additive Endif Return ******************************************************************************** *!* ctlClientToScreen(nhWnd, @nX, @nY) ******************************************************************************** *!* Returns client coords x, y translated into screen coords x, y ******************************************************************************** Function ctlClientToScreen(pnHWnd As Integer, pnX As Integer, pnY As Integer) Local ; m.lcPoint As String, ; m.lnRetVal As Integer m.lcPoint = BinToC(m.pnX, "4RS") + BinToC(m.pnY, "4RS") m.lnRetVal = apiClientToScreen(m.pnHWnd, @m.lcPoint) m.pnX = CToBin(Substr(m.lcPoint , 1, 4), "4RS") m.pnY = CToBin(Substr(m.lcPoint , 5, 4), "4RS") Return m.lnRetVal <> 0 Endfunc ******************************************************************************** *!* ctlComRegister(cFileName) ******************************************************************************** *!* Registers a self registering dll or activex ******************************************************************************** Function ctlComRegister(pcFileName As String) Local ; m.lnHandle As Integer, ; m.llRetVal As Boolean m.llRetVal = FALSE m.lnHandle = apiLoadLibrary(m.pcFileName) If m.lnHandle <> 0 Then If apiGetProcAddress(m.lnHandle, "DllRegisterServer") <> 0 Declare Integer DllRegisterServer In (m.pcFileName) ; As DllRegisterServer_2CC11JLUG If DllRegisterServer_2CC11JLUG() = S_OK Then m.llRetVal = TRUE Endif Clear Dlls DllRegisterServer_2CC11JLUG Endif apiFreeLibrary(m.lnHandle) Endif Return m.llRetVal Endfunc ******************************************************************************** *!* ctlComUnregister(cFileName) ******************************************************************************** *!* Unregisters a self registering dll or activex ******************************************************************************** Function ctlComUnregister(m.pcFileName As String) Local ; m.lnHandle As Integer, ; m.llRetVal As Boolean m.llRetVal = FALSE m.lnHandle = apiLoadLibrary(m.pcFileName) If m.lnHandle <> 0 Then If apiGetProcAddress(m.lnHandle, "DllRegisterServer") <> 0 Declare Integer DllUnregisterServer In (m.pcFileName) ; As DllUnregisterServer_2CC11JLUG If DllUnregisterServer_2CC11JLUG() = S_OK Then m.llRetVal = TRUE Endif Clear Dlls DllUnregisterServer_2CC11JLUG Endif apiFreeLibrary(m.lnHandle) Endif Endfunc ******************************************************************************** *!* ctlCToLargeInteger(cLargeInt) ******************************************************************************** *!* Converts a large integer binary value (8 bytes) to a VFP number ******************************************************************************** Function ctlCToLargeInteger(pcLargeInt As String) Local ; lnLow As Integer, ; lnHigh As Integer, ; lnLargeInt As Integer m.lnLow = CToBin(Left(m.pcLargeInt, 4), "4rs") m.lnHigh = CToBin(Right(m.pcLargeInt, 4), "4rs") m.lnLargeInt = ctlLowHighToLargeInteger(m.lnLow, m.lnHigh) Return m.lnLargeInt Endfunc ******************************************************************************** *!* ctlGetOsVersion() ******************************************************************************** *!* Returns the operating system version in a NTDDI format ******************************************************************************** *!* NTDDI version constants *!* /http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2095548&SiteID=1 *!* #define NTDDI_WIN2K 05000000 *!* #define NTDDI_WIN2KSP1 05000100 *!* #define NTDDI_WIN2KSP2 05000200 *!* #define NTDDI_WIN2KSP3 05000300 *!* #define NTDDI_WIN2KSP4 05000400 *!* #define NTDDI_WINXP 05010000 *!* #define NTDDI_WINXPSP1 05010100 *!* #define NTDDI_WINXPSP2 05010200 *!* #define NTDDI_WINXPSP3 05010300 *!* #define NTDDI_WINXPSP4 05010400 *!* #define NTDDI_WS03 05020000 *!* #define NTDDI_WS03SP1 05020100 *!* #define NTDDI_WS03SP2 05020200 *!* #define NTDDI_WS03SP3 05020300 *!* #define NTDDI_WS03SP4 05020400 *!* #define NTDDI_WIN6 06000000 *!* #define NTDDI_WIN6SP1 06000100 *!* #define NTDDI_WIN6SP2 06000200 *!* #define NTDDI_WIN6SP3 06000300 *!* #define NTDDI_WIN6SP4 06000400 *!* #define NTDDI_VISTA NTDDI_WIN6 *!* #define NTDDI_VISTASP1 NTDDI_WIN6SP1 *!* #define NTDDI_VISTASP2 NTDDI_WIN6SP2 *!* #define NTDDI_VISTASP3 NTDDI_WIN6SP3 *!* #define NTDDI_VISTASP4 NTDDI_WIN6SP4 *!* #define NTDDI_WS08 NTDDI_WIN6SP1 *!* #define NTDDI_WS08SP2 NTDDI_WIN6SP2 *!* #define NTDDI_WS08SP3 NTDDI_WIN6SP3 *!* #define NTDDI_WS08SP4 NTDDI_WIN6SP4 *!* #define NTDDI_LONGHORN NTDDI_VISTA ******************************************************************************** Function ctlGetOsVersion() Return Val(Os(3)) * 1000000 + Val(Os(4)) * 10000 + Val(Os(8)) * 100 + Val(Os(9)) Endfunc ******************************************************************************** *!* ctlGetCaretPos(@nX, @nY) ******************************************************************************** *!* Returns the position of the caret in CLIENT coordinates. ******************************************************************************** Function ctlGetCaretPos(pnX As Integer, pnY As Integer) Local ; m.lcPoint As String, ; m.lnRetVal As Integer m.lcPoint = 0h0000000000000000 m.lnRetVal = apiGetCaretPos(@m.lcPoint) m.pnX = CToBin(Substr(m.lcPoint, 1, 4), "4RS") m.pnY = CToBin(Substr(m.lcPoint, 5, 4), "4RS") Return m.lnRetVal <> 0 Endfunc ******************************************************************************** *!* ctlGetCaretPosX() ******************************************************************************** *!* Returns the X coordinate of the caret position in CLIENT coordinates ******************************************************************************** Function ctlGetCaretPosX() Local m.lcPoint As String m.lcPoint = 0h0000000000000000 apiGetCaretPos(@m.lcPoint) Return CToBin(Substr(m.lcPoint, 1, 4), "4RS") Endfunc ******************************************************************************** *!* ctlGetCaretPosY() ******************************************************************************** *!* Returns the Y coordinate of the caret position in CLIENT coordinates ******************************************************************************** Function ctlGetCaretPosY() Local m.lcPoint As String m.lcPoint = 0h0000000000000000 apiGetCaretPos(@m.lcPoint) Return CToBin(Substr(m.lcPoint, 5, 4), "4RS") Endfunc ******************************************************************************** *!* ctlGetCursorPos(@nX, @nY) ******************************************************************************** *!* Returns the position of the mouse cursor in SCREEN coordinates. ******************************************************************************** Function ctlGetCursorPos(m.pnX As Integer, m.pnY As Integer) Local ; m.lcPoint As String, ; m.lnRetVal As Integer m.lcPoint = 0h0000000000000000 m.lnRetVal = apiGetCursorPos(@m.lcPoint) m.pnX = CToBin(Substr(m.lcPoint, 1, 4), "4RS") m.pnY = CToBin(Substr(m.lcPoint, 5, 4), "4RS") Return m.lnRetVal <> 0 Endfunc ******************************************************************************** *!* ctlGetCursorPosX() ******************************************************************************** *!* Returns the x coordinate position of the mouse cursor in SCREEN coordinates. ******************************************************************************** Function ctlGetCursorPosX() Local m.lcPoint As String m.lcPoint = 0h0000000000000000 apiGetCursorPos(@m.lcPoint) Return CToBin(Substr(m.lcPoint, 1, 4), "4RS") Endfunc ******************************************************************************** *!* ctlGetCursorPosY() ******************************************************************************** *!* Returns the y coordinate position of the mouse cursor in SCREEN coordinates. ******************************************************************************** Function ctlGetCursorPosY() Local m.lcPoint As String m.lcPoint = 0h0000000000000000 apiGetCursorPos(@m.lcPoint) Return CToBin(Substr(m.lcPoint, 5, 4), "4RS") Endfunc ******************************************************************************** *!* ctlHiMetricToPixelsX(nHiMetricX) ******************************************************************************** *!* :http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_20024530.html *!* HIMETRIC / 2540 = INCHES *!* INCHES * 1440 = TWIPS *!* TWIPS / TwipsPerPixel = PIXELS ******************************************************************************** Function ctlHiMetricToPixelsX(m.pnHiMetricX As Integer) Return Round(m.pnHiMetricX / 2540 * 1440 / ctlTwipsPerPixelX(), 0) Endfunc ******************************************************************************** *!* :http://www.experts-exchange.com/Programming/Languages/Visual_Basic/Q_20024530.html *!* HIMETRIC / 2540 = INCHES *!* INCHES * 1440 = TWIPS *!* TWIPS / TwipsPerPixel = PIXELS ******************************************************************************** Function ctlHiMetricToPixelsY(m.pnHiMetricY As Integer) Return Round(m.pnHiMetricY / 2540 * 1440 / ctlTwipsPerPixelY(), 0) Endfunc ******************************************************************************** *!* ctlIsObjectInPage(oControl) ******************************************************************************** *!* Determines if a control is contained in a page somewhere *!* along its object hierarchy ******************************************************************************** Function ctlIsObjectInPage(m.poControl As Control) Local ; m.llIsInPage As Boolean, ; m.loControl As Control m.llIsInPage = FALSE m.loControl = m.poControl Do While Inlist(Upper(m.loControl.BaseClass), "FORM", "TOOLBAR") = FALSE If Upper(m.loControl.BaseClass) == "PAGE" Then m.llIsInPage = TRUE Exit Endif m.loControl = m.loControl.Parent Enddo m.loControl = .Null. m.poControl = .Null. Return m.llIsInPage Endfunc ******************************************************************************** Function ctlIsThemeActive(m.poObject As Object) If Vartype(m.poObject) = T_OBJECT Then Local ; m.loForm As Form, ; m.llFormThemeActive As Boolean, ; m.llControlThemeActive As Boolean *!* Get theme status of object: Do Case Case Pemstatus(m.poObject, "ctlThemes", CON_PEMSTAT_DEFINED) m.llControlThemeActive = m.poObject.ctlThemes Case Pemstatus(m.poObject, "Themes", CON_PEMSTAT_DEFINED) m.llControlThemeActive = m.poObject.Themes Otherwise m.llControlThemeActive = TRUE Endcase *!* Get theme status of parent form m.loForm = m.poObject Do While Inlist(Upper(m.loForm.BaseClass), "FORM", "TOOLBAR") = FALSE m.loForm = m.loForm.Parent Enddo m.llFormThemeActive = m.loForm.Themes m.loForm = .Null. m.poObject = .Null. Return apiIsThemeActive() = 1 And _Screen.Themes And m.llFormThemeActive And m.llControlThemeActive Else Return apiIsThemeActive() <> 0 Endif Endfunc ******************************************************************************** *!* Allocates a block of memory of m.pnBytes *!* Returns a handle to the allocated memory *!* Must be freed after use ******************************************************************************** Function ctlMemAlloc(m.pnBytesToAllocate As Integer) Return apiHeapAlloc(apiGetProcessHeap(), HEAP_ZERO_MEMORY, m.pnBytesToAllocate) Endfunc ******************************************************************************** *!* Frees a block of memory allocated with ctlMemAlloc ******************************************************************************** Function ctlMemFree(m.pnMem As Integer) Return apiHeapFree(apiGetProcessHeap(), 0, m.pnMem) Endfunc ******************************************************************************** *!* Reads from a memory handle exactly m.pnBytes ******************************************************************************** Function ctlMemRead(m.pnMem As Integer, m.pnBytesToRead As Integer) If Vartype(m.pnMem) <> T_NUMERIC Or m.pnMem <= 0 Then Return "" Endif If Vartype(m.pnBytesToRead) <> T_NUMERIC Or m.pnBytesToRead <= 0 Then m.pnBytesToRead = apiHeapSize(apiGetProcessHeap(), 0, m.pnMem) Endif Return Sys(2600, m.pnMem, m.pnBytesToRead) Endfunc ******************************************************************************** *!* Returns the size of a block of memory allocated with ctlMemAlloc *!* Returns -1 on failure ******************************************************************************** Function ctlMemSize(m.pnMem As Integer) Return apiHeapSize(apiGetProcessHeap(), 0, m.pnMem) Endfunc ******************************************************************************** *!* Writes to a memory heap handle, m.pnBytes of m.pcData *!* pads with NULAs if len(m.pcData) < m.pnBytes ******************************************************************************** Function ctlMemWrite(m.pnMem As Integer, m.pcData As String, m.pnBytesToWrite As Integer) If Vartype(m.pcData) = T_NUMERIC Then m.pcData = BinToC(m.pcData, "4rs") Endif If Vartype(m.pnBytesToWrite) = T_NUMERIC And m.pnBytesToWrite > Len(m.pcData) Then m.pcData = m.pcData + Replicate(NULCHAR, m.pnBytesToWrite - Len(m.pcData)) Else m.pnBytesToWrite = Len(m.pcData) Endif If m.pnMem = 0 Then m.pnMem = ctlMemAlloc(m.pnBytesToWrite) Endif m.pcData = Sys(2600, m.pnMem, m.pnBytesToWrite, m.pcData) Return m.pnMem Endfunc ******************************************************************************** *!* converts an integer to an unsigned integer ******************************************************************************** Function ctlIntegerToUnsigned(m.pnValue As Integer) Local lnRetVal If m.pnValue < 0 Then m.lnRetVal = m.pnValue + 4294967296 Else m.lnRetVal = m.pnValue Endif Return m.lnRetVal Endfunc ******************************************************************************** *!* pcValueToReturn can be: T, B, L, R for Top, Bottom, Left, Right *!* This replaces OBJTOCLIENT that has bugs with pageframes ******************************************************************************** Function ctlObjToClient(m.poControl As Control, m.pcValueToReturn As String) Local m.lnPosition As Integer m.pcValueToReturn = Upper(m.pcValueToReturn) m.lnPosition = 0 Do Case Case m.pcValueToReturn $ "TB" *!* 20070711 Modified to account for toolbars Do While Inlist(Upper(m.poControl.BaseClass), "FORM", "TOOLBAR") = FALSE If Pemstatus(m.poControl, "Top", CON_PEMSTAT_DEFINED) Then m.lnPosition = m.lnPosition + m.poControl.Top Endif If Upper(m.poControl.BaseClass) == "PAGE" Then If m.poControl.Parent.TabOrientation = CON_TABOR_TOP Then && Top m.lnPosition = m.lnPosition + ; m.poControl.Parent.Height - ; m.poControl.Parent.PageHeight - ; m.poControl.Parent.BorderWidth * 2 Else m.lnPosition = m.lnPosition + 1 Endif Endif m.poControl = m.poControl.Parent Enddo If m.pcValueToReturn == "B" Then m.lnPosition = m.lnPosition + This.Height Endif Case m.pcValueToReturn $ "LR" *!* 20070711 Modified to account for toolbars Do While Inlist(Upper(m.poControl.BaseClass), "FORM", "TOOLBAR") = FALSE If Pemstatus(m.poControl, "Left", CON_PEMSTAT_DEFINED) Then m.lnPosition = m.lnPosition + m.poControl.Left Endif If Upper(m.poControl.BaseClass) == "PAGE" If m.poControl.Parent.TabOrientation = CON_TABOR_LEFT Then && Left m.lnPosition = m.lnPosition + ; m.poControl.Parent.Width - ; m.poControl.Parent.PageWidth - ; m.poControl.Parent.BorderWidth * 2 Else m.lnPosition = m.lnPosition + 1 Endif Endif m.poControl = m.poControl.Parent Enddo If m.pcValueToReturn == "R" Then m.lnPosition = m.lnPosition + This.Width Endif Endcase Return m.lnPosition Endfunc *!* * Inverse of VFP's DTOS() function. Function ctlSTOD(m.pcDate As String) Local m.ldDate As Date m.ldDate = Date(Val(Substr(m.pcDate,1,4)), Val(Substr(m.pcDate,5,2)), Val(Substr(m.pcDate,7,2))) Return m.ldDate Endfunc ******************************************************************************** *!* Converts a numeric value into a string that represents the number expressed *!* as a size value in bytes, kilobytes, megabytes, or gigabytes, depending on the size. *!* API StrFormatByteSize only work for files up to 4GB *!* Local ; *!* m.lcBuffer As String *!* m.lcBuffer = Space(254) *!* StrFormatByteSize(m.pnSizeInBytes, @m.lcBuffer, Len(m.lcBuffer)) *!* * Remove NUL CHAR *!* m.lcBuffer = Left(m.lcBuffer, At(NULA, m.lcBuffer) - 1) *!* Return m.lcBuffer ******************************************************************************** Function ctlStrFormatByteSize(m.pnSizeInBytes As Number) Local ; m.lnSize As Integer, ; m.lcUnit As String Do Case Case m.pnSizeInBytes < 999 && Bytes m.lnSize = m.pnSizeInBytes m.lcUnit = " Bytes" Case m.pnSizeInBytes < 1024^1 * 999 && KiloBytes m.lnSize = m.pnSizeInBytes / 1024^1 m.lcUnit = " KB" Case m.pnSizeInBytes < 1024^2 * 999 && MegaBytes m.lnSize = m.pnSizeInBytes / 1024^2 m.lcUnit = " MB" Case m.pnSizeInBytes < 1024^3 * 999 && GigaBytes m.lnSize = m.pnSizeInBytes / 1024^3 m.lcUnit = " GB" Otherwise m.lnSize = m.pnSizeInBytes / 1024^4 && TeraBytes m.lcUnit = " TB" Endcase Do Case Case m.lnSize > 100 m.lnSize = Round(m.lnSize , 0) Case m.lnSize > 10 m.lnSize = Round(m.lnSize , 1) Otherwise m.lnSize = Round(m.lnSize , 2) Endcase Return Transform(m.lnSize) + m.lcUnit Endfunc ******************************************************************************** Function ctlStrFormatSeconds(pnSeconds) m.pnSeconds = Round(m.pnSeconds, 0) Local ; m.lcHours As String, ; m.lcMinutes As String, ; m.lcSeconds As String If Int(m.pnSeconds / 3600) > 0 Then m.lcHours = Padl(Alltrim(Str(Int(m.pnSeconds / 3600))), 2, "0") + ":" Else m.lcHours = "" Endif m.lcMinutes = Padl(Alltrim(Str(Int((m.pnSeconds % 3600) / 60))), 2, "0") + ":" m.lcSeconds = Padl(Alltrim(Str((m.pnSeconds % 3600) % 60)), 2, "0") Return m.lcHours + m.lcMinutes + m.lcSeconds Endfunc ******************************************************************************** *!* Converts an unsigned integer to an integer. ******************************************************************************** Function ctlUnsignedToInteger(m.pnValue As Integer) Local m.lnRetVal As Integer If m.pnValue <= 2147483647 Then m.lnRetVal = m.pnValue Else m.lnRetVal= m.pnValue - 4294967296 Endif Return m.lnRetVal Endfunc ******************************************************************************** Function ctlFClose(pnFileHandle As Integer) Local ; lnApiRetVal As Integer, ; llRetVal As Boolean m.lnApiRetVal = apiCloseHandle(m.pnFileHandle) If m.lnApiRetVal = 0 Then m.llRetVal = FALSE Else m.llRetVal = TRUE Endif Return m.llRetVal Endfunc ******************************************************************************** *!* ctlFgets(nFileHandle [, nBytes]) ******************************************************************************** *!* Returns a series of bytes from a file or a communication port opened with a *!* low-level file function until it encounters a carriage return. ******************************************************************************** Function ctlFGets(pnFileHandle As Integer, pnBytesToRead As Integer) Local ; lcByteString As String, ; lnBytesRead As Integer, ; lnApiRetVal As Integer, ; lnOverlapped As Integer, ; lnCrLfPos As Integer, ; lnOffset As Integer If Vartype(m.pnBytesToRead) # T_NUMERIC Then m.pnBytesToRead = 254 Endif m.lnBytesRead = 0 m.lcByteString = Space(m.pnBytesToRead) m.lnOverlapped = 0 m.lnApiRetVal = apiReadFile(m.pnFileHandle, ; @m.lcByteString, ; m.pnBytesToRead , ; @m.lnBytesRead , ; m.lnOverlapped) If m.lnApiRetVal = 0 Then m.lcByteString = "" Else m.lcByteString = Left(m.lcByteString, m.lnBytesRead) Endif *!* Now search for CRLF in the string: m.lnCrLfPos = At(CRLF, m.lcByteString) *!* if we find a CRLF in the string If m.lnCrLfPos <> 0 Then *!* Set file pointer for next read to after CRLF m.lnOffset = (m.lnBytesRead - m.lnCrLfPos - 1) * (-1) ctlFSeek(m.pnFileHandle, m.lnOffset , 1) *!* Remove trailing characters after CRLF m.lcByteString = Left(m.lcByteString, m.lnCrLfPos - 1) Endif Return m.lcByteString Endfunc ******************************************************************************** Function ctlFileTimeToDateTime(poFileTime As _FILETIME) Local ; loSystemTime As _SYSTEMTIME, ; ltFileDateTime As Datetime m.loSystemTime = Createobject("_SYSTEMTIME") If apiFileTimeToSystemTime(m.poFileTime.Address, m.loSystemTime.Address) = 1 Then With m.loSystemTime m.ltFileDateTime = Datetime(.wYear, .wMonth, .wDay, .wHour, .wMinute, .wSecond) Endwith Else m.ltFileDateTime = Ctot("") Endif m.loSystemTime = .Null. Return m.ltFileDateTime Endfunc ******************************************************************************** Function ctlFontHeightToPoints(pnHeight As Integer) Local ; lnDc As Integer, ; lnLogPixelsY As Integer m.lnDc = apiGetDC(HWND_DESKTOP) m.lnLogPixelsY = apiGetDeviceCaps(m.lnDc, LOGPIXELSY) apiReleaseDC(HWND_DESKTOP, m.lnDc) Return Round(72 * m.pnHeight / m.lnLogPixelsY * (-1), 0) Endfunc ******************************************************************************** Function ctlFontPointsToHeight(pnPoints As Integer) Local ; lnDc As Integer, ; lnLogPixelsY As Integer m.lnDc = apiGetDC(HWND_DESKTOP) m.lnLogPixelsY = apiGetDeviceCaps(m.lnDc, LOGPIXELSY) apiReleaseDC(HWND_DESKTOP, m.lnDc) Return apiMulDiv(m.pnPoints, m.lnLogPixelsY, 72) * (-1) Endfunc ******************************************************************************** *!* ctlFopen(cFilename [, nAttribute]) ******************************************************************************** *!* 0 READ-ONLY BUFFERED *!* 1 WRITE-ONLY BUFFERED *!* 2 READ-WRITE BUFFERED *!* 10 READ-ONLY UNBUFFERED *!* 11 WRITE-ONLY UNBUFFERED *!* 12 READ-WRITE UNBUFFERED ******************************************************************************** Function ctlFOpen(pcFileName As String, pnAttribute As Integer) Local ; lcFilename As String, ; lnDesiredAccess As Integer, ; lnShareMode As Integer, ; lnSecurityAttributes As Integer, ; lnCreationDisposition As Integer, ; lnFlagsAndAttributes As Integer, ; lnTemplateFile As Integer, ; lnBufferFlag As Integer, ; lnFileHandle As Integer m.lcFilename = Alltrim(m.pcFileName) If Vartype(m.pnAttribute) # T_NUMERIC Then m.pnAttribute = 0 Endif Do Case Case m.pnAttribute = 0 m.lnDesiredAccess = GENERIC_READ m.lnBufferFlag = 0 Case m.pnAttribute = 1 m.lnDesiredAccess = GENERIC_WRITE m.lnBufferFlag = 0 Case m.pnAttribute = 2 m.lnDesiredAccess = Bitor(GENERIC_READ, GENERIC_WRITE) m.lnBufferFlag = 0 Case m.pnAttribute = 10 m.lnDesiredAccess = GENERIC_READ m.lnBufferFlag = FILE_FLAG_WRITE_THROUGH Case m.pnAttribute = 11 m.lnDesiredAccess = GENERIC_WRITE m.lnBufferFlag = FILE_FLAG_WRITE_THROUGH Case m.pnAttribute = 12 m.lnDesiredAccess = Bitor(GENERIC_READ, GENERIC_WRITE) m.lnBufferFlag = FILE_FLAG_WRITE_THROUGH Otherwise m.lnDesiredAccess = GENERIC_READ m.lnBufferFlag = 0 Endcase m.lnShareMode = 0 m.lnSecurityAttributes = 0 m.lnCreationDisposition = OPEN_EXISTING m.lnFlagsAndAttributes = Bitor(FILE_ATTRIBUTE_NORMAL, m.lnBufferFlag) m.lnTemplateFile = 0 m.lnFileHandle = apiCreateFile( ; m.lcFilename, ; m.lnDesiredAccess, ; m.lnShareMode, ; m.lnSecurityAttributes, ; m.lnCreationDisposition, ; m.lnFlagsAndAttributes, ; m.lnTemplateFile) Return m.lnFileHandle Endfunc ******************************************************************************** Function ctlFRead(pnFileHandle As Integer, pnBytesToRead As Integer) Local ; lcByteString As String, ; lnBytesRead As Integer, ; lnApiRetVal As Integer, ; lnOverlapped As Integer m.lnBytesRead = 0 m.lcByteString = Space(m.pnBytesToRead) m.lnOverlapped = 0 m.lnApiRetVal = apiReadFile(m.pnFileHandle, ; @m.lcByteString, ; m.pnBytesToRead , ; @m.lnBytesRead , ; m.lnOverlapped) If m.lnApiRetVal = 0 Then m.lcByteString = "" Else m.lcByteString = Left(m.lcByteString, m.lnBytesRead) Endif Return m.lcByteString Endfunc ******************************************************************************** *!* _Fseek(nFileHandle, nBytesMoved ", nRelativePosition") *!* #DEFINE FILE_BEGIN 0 *!* #DEFINE FILE_CURRENT 1 *!* #DEFINE FILE_END 2 *!* #DEFINE INVALID_SET_FILE_POINTER -1 ******************************************************************************** Function ctlFSeek(pnFileHandle As Integer, pnBytesMoved As Integer , pnRelativePosition As Integer) Local ; lnLow As Integer, ; lnHigh As Integer, ; lcNewFilePointer As String, ; lnNewFilePointer As Integer, ; lnApiRetVal As Integer If Vartype(m.pnRelativePosition) # T_NUMERIC Then m.pnRelativePosition = 0 Endif *!* Split large integer into low unsigned and high signed m.lnLow = 0 m.lnHigh = 0 ctlLargeIntegerToLowHigh(m.pnBytesMoved, @m.lnLow, @m.lnHigh) m.lcNewFilePointer = Replicate(NULCHAR, 8) m.lnApiRetVal = ; apiSetFilePointerEx( ; m.pnFileHandle , ; m.lnLow , ; m.lnHigh, ; @m.lcNewFilePointer, ; m.pnRelativePosition ) If m.lnApiRetVal = 0 Then m.lnNewFilePointer = -1 Else m.lnNewFilePointer = ctlCToLargeInteger(m.lcNewFilePointer) Endif Return m.lnNewFilePointer Endfunc ******************************************************************************** *!* ctlFSize(cFilename|nFileHandle) ******************************************************************************** Function ctlFSize(puFnameOrFhandle As variant) Local ; m.lnFileSize As Integer, ; m.llCloseFile As Boolean, ; m.lnFileHandle As Integer, ; m.lcLargeInt As String, ; m.lnApiRetVal As Integer m.lnFileSize = -1 m.lnFileHandle = HFILE_ERROR m.llCloseFile = FALSE Do Case Case Vartype(m.puFnameOrFhandle) = T_NUMERIC m.lnFileHandle = m.puFnameOrFhandle Case Vartype(m.puFnameOrFhandle) = T_CHARACTER m.llCloseFile = TRUE m.lnFileHandle = ctlFOpen(m.puFnameOrFhandle, 0) Otherwise Return m.lnFileSize Endcase If m.lnFileHandle <> HFILE_ERROR m.lcLargeInt = Replicate(NULCHAR, 8) m.lnApiRetVal = apiGetFileSizeEx(m.lnFileHandle, @m.lcLargeInt) If m.lnApiRetVal <> 0 Then m.lnFileSize = ctlCToLargeInteger(m.lcLargeInt) Endif Endif *!* Close file If m.llCloseFile = TRUE ctlFClose(m.lnFileHandle) Endif Return m.lnFileSize Endfunc ******************************************************************************** *!* ctlFwrite(nFileHandle, cExpression [, nCharactersWritten]) ******************************************************************************** Function ctlFWrite(m.pnFileHandle As Integer, m.pcExpression As String, m.pnCharactersWritten As Integer) Local ; m.lnBytesWritten As Integer, ; m.lnOverlapped As Integer, ; m.lnApiRetVal As Integer m.lnBytesWritten = 0 m.lnOverlapped = 0 If Vartype(m.pnCharactersWritten) <> T_NUMERIC Then m.pnCharactersWritten = Len(m.pcExpression) Endif m.lnApiRetVal = apiWriteFile(m.pnFileHandle, ; m.pcExpression, ; m.pnCharactersWritten , ; @m.lnBytesWritten, ; m.lnOverlapped) Return m.lnBytesWritten Endfunc ******************************************************************************** Function ctlLargeIntegerToC(m.pnLargeInt As Integer) Local ; m.lnLow As Integer, ; m.lnHigh As Integer, ; m.lcLargeInt As String m.lnLow = 0 m.lnHigh = 0 ctlLargeIntegerToLowHigh(m.pnLargeInt, @m.lnLow, @m.lnHigh) m.lcLargeInt = BinToC(m.lnLow, "4rs") + BinToC(m.lnHigh, "4rs") Return m.lcLargeInt Endfunc ******************************************************************************** *!* ctlLargeIntegerToLowHigh(nLargeInt, @nLow, @nHigh) ******************************************************************************** Function ctlLargeIntegerToLowHigh(m.pnLargeInt, m.lnLow, m.lnHigh) m.lnLow = m.pnLargeInt % 2^32 m.lnHigh = Int((m.pnLargeInt - m.lnLow) / 2^32) If m.lnLow < 0 Then m.lnLow = m.lnLow + 2^32 Endif Return Endfunc ******************************************************************************** Function ctlLowHighToLargeInteger(pnLow As Integer, pnHigh As Integer) Local lnLargeInt As Integer If m.pnLow < 0 Then m.pnLow = m.pnLow + 2^32 Endif m.lnLargeInt = m.pnLow + m.pnHigh * 2^32 Return m.lnLargeInt Endfunc ******************************************************************************** *!* ctlGetLangId ******************************************************************************** *!* pnLocale could be LOCALE_USER_DEFAULT, LOCALE_SYSTEM_DEFAULT *!* /http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_34rz.asp *!* /http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_8xo3.asp *!* /http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_61df.asp *!* Sets the value of strings that are language dependant. ******************************************************************************** Function ctlGetLangId(m.pnLocale As Integer, m.pnWhatToReturn As Integer) Local ; m.lnLocale As Integer, ; m.lcLocaleInfo As String, ; m.lnCharsRet As Integer, ; m.lnLangID As Integer, ; m.lnPrimaryLangID As Integer, ; m.lnSubLangID As Integer, ; m.lnRetVal As Integer If Pcount() > 0 .And. Vartype(m.pnLocale) = T_NUMERIC Then m.lnLocale = m.pnLocale Else m.lnLocale = LOCALE_SYSTEM_DEFAULT Endif m.lcLocaleInfo = Replicate(NULCHAR, 5) m.lnCharsRet = apiGetLocaleInfo(m.pnLocale , LOCALE_ILANGUAGE, @m.lcLocaleInfo, Len(m.lcLocaleInfo)) *!* remove nul chars m.lcLocaleInfo = Strtran(m.lcLocaleInfo, NULCHAR, "") *!* m.lcLocaleInfo is now a character representation of a hex number m.lnLangID = Evaluate("0x" + m.lcLocaleInfo) *!* m.lnPrimaryLangID = Bitand(m.lnLangID, 0x3FF) *!* m.lnSubLangID = Bitrshift(m.lnLangID, 10) Do Case Case Pcount() < 2 Or m.pnWhatToReturn = 1 m.lnRetVal = m.lnLangID Case m.pnWhatToReturn = 2 m.lnRetVal = Bitand(m.lnLangID, 0x3FF) Case m.pnWhatToReturn = 3 m.lnRetVal = Bitrshift(m.lnLangID, 10) Otherwise m.lnRetVal = m.lnLangID Endcase Return m.lnRetVal Endfunc ******************************************************************************** *!* pnLocale could be LOCALE_USER_DEFAULT, LOCALE_SYSTEM_DEFAULT ******************************************************************************** Function ctlGetPrimaryLangID(m.pnLocale As Integer) Return ctlGetLangId(m.pnLocale, 2) Endfunc ******************************************************************************** *!* Returns the height of a certain string in the font selected into a hwnd ******************************************************************************** Function ctlGetStringHeightFromHwnd(m.pcString, m.pnHWnd) Local ; m.lnDc As Integer, ; m.lnHeight As Integer, ; m.lnWidth As Integer, ; m.lcSize As String, ; m.lnFont As Integer, ; m.lnPrevFont As Integer *!* Get font m.lnFont = apiSendMessageInteger(m.pnHWnd, WM_GETFONT, 0, 0) *!* Get DC m.lnDc = apiGetDC(m.pnHWnd) *!* Apply font to DC, we get previous font as result m.lnPrevFont = apiSelectObject(m.lnDc, m.lnFont) m.lcSize = Space(8) apiGetTextExtentPoint32(m.lnDc, m.pcString, Len(m.pcString), @ m.lcSize) m.lnWidth = CToBin(Substr(m.lcSize, 1, 4), "4RS") && Width m.lnHeight = CToBin(Substr(m.lcSize, 5, 4), "4RS") && Height *!* Restore previous font apiSelectObject(m.lnDc, m.lnPrevFont ) *!* Release DC apiReleaseDC(m.pnHWnd, m.lnDc) Return m.lnWidth Endfunc Function ctlGetStringWidthFromHwnd(m.lcString, m.lnHwnd) Endfunc ******************************************************************************** *!* pnLocale could be LOCALE_USER_DEFAULT, LOCALE_SYSTEM_DEFAULT ******************************************************************************** Function ctlGetSubLangID(m.pnLocale As Integer) Return ctlGetLangId(m.pnLocale, 3) Endfunc ******************************************************************************** Function ctlGetPrimaryLangIDFromLangID(m.pnLangID As Integer) Return Bitand(m.pnLangID, 0x3FF) Endfunc ******************************************************************************** Function ctlGetSubLangIDFromLangID(m.pnLangID As Integer) Return Bitrshift(m.pnLangID, 10) Endfunc ******************************************************************************** *!* ctlGetHostHWnd(Object) ******************************************************************************** *!* Returns the HWnd of the form that contains an object, if any *!* If the object has no parent, returns _VFP.HWnd *!* If the form is a top level form or has scrollbars, *!* returns the HWnd of the inner window. *!* Parameter can be a form, toolbar or control ******************************************************************************** Function ctlGetHostHWnd(m.poObject As Object) Local m.nhWnd As Integer *!* traverse the object hierarchy until we find the form: *!* Modified 20070603 to check for toolbars *!* Do While Inlist(Upper(m.poObject.BaseClass), "FORM", "TOOLBAR") = FALSE *!* m.poObject = m.poObject.Parent *!* Enddo *!* 20080405 modified to check for HWnd property of parent *!* and to check if parent is an object *!* Check if we already have a form or toolbar: If Inlist(Upper(m.poObject.BaseClass), "FORM", "TOOLBAR") Then m.nhWnd = m.poObject.HWnd Else *!* Check if object is contained in another object: If Type("m.poObject.Parent") = T_UNDEFINED Then m.nhWnd = _vfp.HWnd Else *!* Get first parent: m.poObject = m.poObject.Parent *!* Traverse object hierarchy upwards until we find an object with a HWnd: Do While Pemstatus(m.poObject, "HWnd", 5) = FALSE If Type("m.poObject.Parent") = T_UNDEFINED Then m.nhWnd = _vfp.HWnd Exit Else m.poObject = m.poObject.Parent Endif Enddo m.nhWnd = m.poObject.HWnd Endif Endif *!* If we have a form, and the form is a top level form, or it has scrollbars, *!* get hWnd of inner window: If Upper(m.poObject.BaseClass) = "FORM" Then If m.poObject.ShowWindow = 2 Or m.poObject.ScrollBars > 0 Then *!* Get hWnd of client window of Top Level Form //Craig Boyd// If Version(CON_VER_NUM) >= 900 m.nhWnd = Sys(2327, Sys(2325, Sys(2326, m.poObject.HWnd))) Else m.nhWnd = apiGetWindow(m.poObject.HWnd, GW_CHILD) Endif Endif Endif m.poObject = .Null. Release m.poObject Return m.nhWnd Endfunc ******************************************************************************** *!* ctlGetHostHWnd() *!* Returns the HWnd of a form, or the HWnd of the inner window in case of *!* top level forms or forms with scrollbars *!* Parameter can be a form, toolbar or control ******************************************************************************** Function ctlGetHostHWnd(m.poObject As Object) Local ; m.loForm As Form, ; m.nhWnd As Integer *!* traverse the object hierarchy until we find the form: *!* Modified 20070603 to check for toolbars Do While Inlist(Upper(m.poObject.BaseClass), "FORM", "TOOLBAR") = FALSE m.poObject = m.poObject.Parent Enddo m.loForm = m.poObject m.poObject = Null m.nhWnd = m.loForm.HWnd *!* If the form is a top level form, or it has scrollbars, get hWnd of inner window: If Upper(m.loForm.BaseClass) = "FORM" Then If m.loForm.ShowWindow = 2 Or m.loForm.ScrollBars > 0 Then *!* Get hWnd of client window of Top Level Form //Craig Boyd// If Version(CON_VER_NUM) >= 900 m.nhWnd = Sys(2327, Sys(2325, Sys(2326, m.loForm.HWnd))) Else m.nhWnd = apiGetWindow(m.loForm.HWnd, GW_CHILD) Endif Endif Endif m.loForm = Null Return m.nhWnd Endfunc ******************************************************************************** *!* int GET_X_LPARAM( *!* LPARAM lParam *!* ); *!* Parameters *!* lParam *!* Specifies the value to be converted. *!* Return Value *!* The return value is the low-order int of the specified value. ******************************************************************************** Function ctlGet_X_lParam(m.pnlParam As Integer) Return Bitand(m.pnlParam, 0xFFFF) Endfunc ******************************************************************************** Function ctlGetXFromLparam(m.pnlParam As Integer) Return Bitand(m.pnlParam, 0xFFFF) Endfunc ******************************************************************************** *!* int GET_Y_LPARAM( *!* LPARAM lParam *!* ); *!* Parameters *!* lParam *!* Specifies the value to be converted. *!* Return Value *!* The return value is the high-order int of the specified value. ******************************************************************************** Function ctlGet_Y_lParam(m.pnlParam As Integer) Return Bitrshift(m.pnlParam, 16) && Bitand(Int(m.pnlParam / 0x10000), 0xFFFF) Endfunc ******************************************************************************** Function ctlGetUserName Local m.lcBuffer, m.lnBufferLen m.lcBufferLen = UNLEN + 1 m.lcBuffer = Replicate(NULCHAR, m.lcBufferLen) apiGetUserName(@m.lcBuffer, @m.lcBufferLen) Return Left(m.lcBuffer, m.lcBufferLen - 1) Endfunc ******************************************************************************** Function ctlGetYFromLparam(m.pnlParam As Integer) Return Bitrshift(m.pnlParam, 16) && Bitand(Int(m.pnlParam / 0x10000), 0xFFFF) Endfunc ******************************************************************************** Function ctlGetWindowProcedure(m.pnHWnd As Integer) If Empty(m.pnHWnd) Then m.pnHWnd = _vfp.HWnd Endif Return apiGetWindowLong(m.pnHWnd, GWL_WNDPROC) Endfunc ******************************************************************************** *!* BYTE HIBYTE( *!* Word wValue *!* ); *!* Parameters *!* wValue *!* Specifies the Value To be converted. *!* Return Value *!* the Return Value Is the High-Order BYTE Of the specified Value. ******************************************************************************** Function ctlHiByte(m.pnlParam As Integer) Return Bitrshift(m.pnlParam, 8) && Bitand(Int(m.pnlParam / 0x10000), 0xFFFF) Endfunc ******************************************************************************** *!* BYTE LOBYTE( *!* Word wValue *!* ); *!* Parameters *!* wValue *!* Specifies the Value To be converted. *!* Return Value *!* the Return Value Is the low-Order BYTE Of the specified Value. ******************************************************************************** Function ctlLoByte(m.pnlParam As Integer) Return Bitand(m.pnlParam , 0xFF) Endfunc ******************************************************************************** *!* Word HIWORD( *!* DWORD dwValue *!* ); *!* Parameters *!* dwValue *!* Specifies the Value To be converted. *!* Return Value *!* the Return Value Is the High-Order Word Of the specified Value. ******************************************************************************** Function ctlHiWord(m.pnlParam As Integer) Return Bitrshift(m.pnlParam, 16) && Bitand(Int(m.pnlParam / 0x10000), 0xFFFF) Endfunc ******************************************************************************** *!* Word LOWORD( *!* DWORD dwValue *!* ); *!* Parameters *!* dwValue *!* Specifies the Value To be converted. *!* Return Value *!* the Return Value Is the low-Order Word Of the specified Value. ******************************************************************************** Function ctlLoWord(m.pnlParam As Integer) Return Bitand(m.pnlParam, 0xFFFF) Endfunc Function ctlGetStringResource(pcResource As String, pnStringId As Integer) Local ; lnModule As Integer, ; llReleaseLibrary As Boolean, ; lcString As String *!* Get module handle of user32 if it is loaded m.lnModule = apiGetModuleHandle(m.pcResource) *!* If not loaded, load it If m.lnModule = 0 Then m.llReleaseLibrary = TRUE m.lnModule = apiLoadLibrary(m.pcResource) Else m.llReleaseLibrary = FALSE Endif m.lcString = Replicate(NULA, 1024) m.lnStringLen = apiLoadString(m.lnModule, m.pnStringId, @m.lcString, Len(m.lcString)) m.lcString = Left(m.lcString, m.lnStringLen) If m.llReleaseLibrary = TRUE Then apiFreeLibrary(m.lnModule) Endif Return m.lcString Endfunc ******************************************************************************** *!* DWORD MAKELONG( *!* Word wLow, *!* Word wHigh *!* ); *!* Parameters *!* wLow *!* Specifies the low-Order Word Of the new Value. *!* wHigh *!* Specifies the High-Order Word Of the new Value. *!* Return Value *!* the Return Value Is a Long Value. ******************************************************************************** Function ctlMakeLong(m.pnLow As Integer, m.pnHigh As Integer) Return m.pnLow + m.pnHigh * 0x10000 && Bitor(m.wLow, BITLSHIFT(m.wHigh, 16) Endfunc ******************************************************************************** *!* LPARAM MAKELPARAM( *!* WORD wLow, *!* WORD wHigh *!* ); *!* Parameters *!* wLow *!* Specifies the low-order word of the new value. *!* wHigh *!* Specifies the high-order word of the new value. *!* Return Value *!* The return value is an LPARAM value. ******************************************************************************** Function ctlMakelParam(m.pnLow As Integer, m.pnHigh As Integer) Return m.pnLow + m.pnHigh * 0x10000 && Bitor(m.wLow, BITLSHIFT(m.wHigh, 16) Endfunc ******************************************************************************** *!* POINT *!* The POINT structure defines the x- and y- coordinates of a point. *!* typedef struct tagPOINT { *!* LONG x; *!* LONG y; *!* } POINT, *PPOINT; *!* Members *!* x *!* Specifies the x-coordinate of the point. *!* y *!* Specifies the y-coordinate of the point. *!* This is not a Windows Macro ******************************************************************************** Function ctlMakePoint(m.pnX As Integer, m.pnY As Integer) Return BinToC(m.pnX, "4RS") + BinToC(m.pnY, "4RS") Endfunc ******************************************************************************** Function ctlMakewParam(m.pnLow As Integer, m.pnHigh As Integer) ******************************************************************************** Return ctlMakelParam(m.pnLow, m.pnHigh) Endfunc ******************************************************************************** *!* POINT *!* The POINT structure defines the x- and y- coordinates of a point. *!* typedef struct tagPOINT { *!* LONG x; *!* LONG y; *!* } POINT, *PPOINT; *!* Members *!* x *!* Specifies the x-coordinate of the point. *!* y *!* Specifies the y-coordinate of the point. *!* This is not a Windows Macro ******************************************************************************** Function ctlGetXFromPoint(m.pcPoint As String) Return CToBin(Substr(m.pcPoint, 1, 4), "4RS") Endfunc ******************************************************************************** *!* POINT *!* The POINT structure defines the x- and y- coordinates of a point. *!* typedef struct tagPOINT { *!* LONG x; *!* LONG y; *!* } POINT, *PPOINT; *!* Members *!* x *!* Specifies the x-coordinate of the point. *!* y *!* Specifies the y-coordinate of the point. *!* This is not a Windows Macro ******************************************************************************** Function ctlGetYFromPoint(m.pcPoint As String) Return CToBin(Substr(m.pcPoint, 5, 4), "4RS") Endfunc ******************************************************************************** *!* This returns an object reference to the parent form *!* of a non top level form: *!* the _Screen, or some Top Level Form *!* accepts as parameter a form reference ******************************************************************************** Function ctlGetParentForm(m.poForm As Form) Local ; m.lnHwnd As Integer, ; m.loForm As Form, ; m.lnX As Integer m.lnHwnd = apiGetParent(m.poForm.HWnd) If _Screen.HWnd = m.lnHwnd Then m.loForm = _Screen Else *!* Parent is a Top Level Form, get HWnd of form, what we have *!* now is HWnd of inner window of Top Level Form: m.lnHwnd = apiGetParent(m.lnHwnd) *!* Find the Top Level Form that has this HWnd: For m.lnX = 1 To _Screen.FormCount If _Screen.Forms(m.lnX).HWnd = m.lnHwnd Then m.loForm = _Screen.Forms(m.lnX) Exit Endif Endfor Endif Return m.loForm Endfunc ******************************************************************************** *!* Returns current date formated string *!* 1 DATE_SHORTDATE *!* 2 DATE_LONGDATE ******************************************************************************** Function ctlGetDateFormat(pnFlags As Integer) Local ; lnLocale As Integer, ; lcDate As String, ; lcFormat As String, ; lcDateStr As String, ; lnDateStrLen As Integer, ; lnFlags As Integer If Vartype(m.pnFlags) # T_NUMERIC Then m.lnFlags = DATE_LONGDATE Else m.lnFlags = m.pnFlags Endif m.lnLocale = LOCALE_USER_DEFAULT m.lcDate = .Null. m.lcFormat = .Null. m.lnDateStrLen = 0xFF m.lcDateStr = Space(m.lnDateStrLen) m.lnDateStrLen = apiGetDateFormat( ; m.lnLocale, ; m.lnFlags, ; @m.lcDate, ; @m.lcFormat, ; @m.lcDateStr, ; m.lnDateStrLen) m.lcDateStr= Left(m.lcDateStr, m.lnDateStrLen - 1) Return m.lcDateStr Endfunc Function ctlGetDateFormatEx(pdDate, pnLocale, pnFlags) Local ; lcDate As String, ; lcFormat As String, ; lcDateStr As String, ; lnDateStrLen As Integer, ; ldDate As Date, ; lnLocale As Integer, ; lnFlags As Integer If Vartype(m.pdDate) # T_DATE Then m.ldDate = Date() Else m.ldDate = m.pdDate Endif If Vartype(m.pnLocale) # T_NUMERIC Then m.lnLocale = LOCALE_USER_DEFAULT Else m.lnLocale = m.pnLocale Endif If Vartype(m.pnFlags) # T_NUMERIC Then m.lnFlags = DATE_LONGDATE Else m.lnFlags = m.pnFlags Endif *!* .http://msdn.microsoft.com/en-us/library/ms724950(VS.85).aspx *!* typedef struct _SYSTEMTIME { *!* WORD wYear; *!* WORD wMonth; *!* WORD wDayOfWeek; *!* WORD wDay; *!* WORD wHour; *!* WORD wMinute; *!* WORD wSecond; *!* WORD wMilliseconds; *!* *!* } SYSTEMTIME m.lcDate = ; BinToC(Year(m.ldDate), "2rs") + ; BinToC(Month(m.ldDate), "2rs") + ; BinToC(Dow(m.ldDate, 1), "2rs") + ; BinToC(Day(m.ldDate), "2rs") + ; 0h0000 + ; 0h0000 + ; 0h0000 + ; 0h0000 m.lcFormat = .Null. m.lnDateStrLen = 0xFF m.lcDateStr = Space(m.lnDateStrLen) m.lnDateStrLen = apiGetDateFormat( ; m.lnLocale, ; m.lnFlags, ; m.lcDate, ; m.lcFormat, ; @m.lcDateStr, ; m.lnDateStrLen) m.lcDateStr= Left(m.lcDateStr, m.lnDateStrLen - 1) Return m.lcDateStr Endfunc ******************************************************************************** *!* Returns the type of container a control is in, or the type of form *!* accepts as parameter a control or a form reference *!* CON_FORMTYPE_DEFAULT 0 *!* CON_FORMTYPE_TOPLEVEL 1 *!* CON_FORMTYPE_SCREEN 2 *!* Determine the type of form the control parameter is in, *!* or the type of form, if the passed parameter is a form *!* Parameter can be a form, toolbar or control ******************************************************************************** Function ctlGetFormType(m.poObject As Object) Local ; m.loForm As Form, ; m.lnFormType As Integer m.loForm = m.poObject *!* Go up the object hierarchy until we find a form: *!* 20070711 Modified to account for toolbars Do While Inlist(Upper(m.loForm.BaseClass), "FORM", "TOOLBAR") = FALSE If Type("m.loForm.Parent") = T_OBJECT Then m.loForm = m.loForm.Parent Else m.loForm = _Screen.ActiveForm Exit Endif Enddo m.lnFormType = CON_FORMTYPE_DEFAULT *!* If container is a TLF, must have ShowWindow = 2 If m.loForm.ShowWindow = CON_SHOWWIN_ASTOPLEVELFORM Then m.lnFormType = CON_FORMTYPE_TOPLEVEL Endif *!* If Form.Name equals the _Screen.Name, then container is _Screen If m.loForm.Name == _Screen.Name Then m.lnFormType = CON_FORMTYPE_SCREEN Endif m.loForm = Null Return m.lnFormType Endfunc ******************************************************************************** Function ctlTwipsPerPixelX() Local ; m.lnDc As Integer, ; m.lnLogPixelsX As Integer m.lnDc = apiGetDC(HWND_DESKTOP) m.lnLogPixelsX = apiGetDeviceCaps(m.lnDc, LOGPIXELSX) apiReleaseDC(HWND_DESKTOP, m.lnDc) Return Round(1440 / m.lnLogPixelsX, 0) Endfunc ******************************************************************************** Function ctlTwipsPerPixelY() Local ; m.lnDc As Integer, ; m.lnLogPixelsY As Integer m.lnDc = apiGetDC(HWND_DESKTOP) m.lnLogPixelsY = apiGetDeviceCaps(m.lnDc, LOGPIXELSY) apiReleaseDC(HWND_DESKTOP, m.lnDc) Return Round(1440 / m.lnLogPixelsY, 0) Endfunc ******************************************************************************** *!* GUID FUNCTIONS ******************************************************************************** *!* http://www.ietf.org/rfc/rfc4122.txt *!* http://en.wikipedia.org/wiki/Globally_Unique_Identifier *!* http://en.wikipedia.org/wiki/Universally_Unique_Identifier ******************************************************************************** *!* Returns a new binary 16 byte GUID *!* In Windows NT 4.0, Windows Me/98, and Windows 95 DCOM release, UuidCreate returns *!* RPC_S_UUID_LOCAL_ONLY when the originating computer does not have an ethernet/token ring *!* (IEEE 802.x) address. In this case, the generated UUID is a valid identifier, and is guaranteed *!* to be unique among all UUIDs generated on the computer. However, the possibility exists that *!* another computer without an ethernet/token ring address generated the identical UUID. *!* Therefore you should never use this UUID to identify an object that is not strictly local to *!* your computer. Computers with ethernet/token ring addresses generate UUIDs that are guaranteed *!* to be globally unique. ******************************************************************************** Function ctlNewGuid() Local m.lcGuid As String m.lcGuid = Replicate(Chr(0xFF), 16) apiUuidCreate(@m.lcGuid) Return m.lcGuid Endfunc ******************************************************************************** Function ctlNewGuidNil() Local m.lcGuid As String m.lcGuid = Replicate(Chr(0xFF), 16) apiUuidCreateNil(@m.lcGuid) Return m.lcGuid Endfunc ******************************************************************************** Function ctlNewGuidSequential() Local m.lcGuid As String m.lcGuid = Replicate(Chr(0xFF), 16) apiUuidCreateSequential(@m.lcGuid) Return m.lcGuid Endfunc ******************************************************************************** *!* Returns a new 32 char GUID string *!* Format "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ******************************************************************************** Function ctlNewGuidString32() Return ctlGuidToString32(ctlNewGuid()) Endfunc ******************************************************************************** *!* Returns a new 36 char GUID string *!* Format "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" ******************************************************************************** Function ctlNewGuidString36() Return ctlGuidToString36(ctlNewGuid()) Endfunc ******************************************************************************** *!* Returns a new 38 char GUID string *!* Format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" ******************************************************************************** Function ctlNewGuidString38() Return ctlGuidToString38(ctlNewGuid()) Endfunc ******************************************************************************** *!* Converts a binary 16 byte GUID to a 32 char GUID string *!* format "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ******************************************************************************** Function ctlGuidToString32(pcGuid As String) Local m.lcGuidString As String m.lcGuidString = "" *!* Reorder GUID bytes m.lcGuidString = ; Substr(m.pcGuid, 4, 1) + ; Substr(m.pcGuid, 3, 1) + ; Substr(m.pcGuid, 2, 1) + ; Substr(m.pcGuid, 1, 1) + ; Substr(m.pcGuid, 6, 1) + ; Substr(m.pcGuid, 5, 1) + ; Substr(m.pcGuid, 8, 1) + ; Substr(m.pcGuid, 7, 1) + ; Substr(m.pcGuid, 9, 8) *!* Convert bytes to encoded HexBinary m.lcGuidString = Strconv(m.lcGuidString, 15) Return m.lcGuidString Endfunc ******************************************************************************** *!* Converts a binary 16 byte GUID to a 36 char GUID string *!* format "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" *!* This is faster that using the StringFromGuid2 API call ******************************************************************************** Function ctlGuidToString36(pcGuid As String) Local ; m.lcGuidString As String, ; m.lcGuid As String m.lcGuidString = "" *!* Convert bytes to encoded HexBinary m.lcGuid = Strconv(m.pcGuid, 15) *!* Reorder GUID bytes, Add hyphens m.lcGuidString = ; Substr(m.lcGuid, 07, 02) + ; Substr(m.lcGuid, 05, 02) + ; Substr(m.lcGuid, 03, 02) + ; Substr(m.lcGuid, 01, 02) + ; "-" + ; Substr(m.lcGuid, 11, 02) + ; Substr(m.lcGuid, 09, 02) + ; "-" + ; Substr(m.lcGuid, 15, 02) + ; Substr(m.lcGuid, 13, 02) + ; "-" + ; Substr(m.lcGuid, 17, 04) + ; "-" + ; Substr(m.lcGuid, 21, 12) Return m.lcGuidString Endfunc ******************************************************************************** *!* Converts a binary 16 byte GUID to a 38 char GUID string *!* format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" *!* This is faster that using the StringFromGuid2 API call ******************************************************************************** Function ctlGuidToString38(pcGuid As String) Local ; m.lcGuidString As String, ; m.lcGuid As String m.lcGuidString = "" *!* Convert bytes to encoded HexBinary m.lcGuid = Strconv(m.pcGuid, 15) *!* Reorder GUID bytes, Add brackets, hyphens m.lcGuidString = ; "{" + ; Substr(m.lcGuid, 07, 02) + ; Substr(m.lcGuid, 05, 02) + ; Substr(m.lcGuid, 03, 02) + ; Substr(m.lcGuid, 01, 02) + ; "-" + ; Substr(m.lcGuid, 11, 02) + ; Substr(m.lcGuid, 09, 02) + ; "-" + ; Substr(m.lcGuid, 15, 02) + ; Substr(m.lcGuid, 13, 02) + ; "-" + ; Substr(m.lcGuid, 17, 04) + ; "-" + ; Substr(m.lcGuid, 21, 12) + ; "}" Return m.lcGuidString Endfunc ******************************************************************************** *!* Converts char GUID string to a binary 16 byte GUID *!* format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" *!* format "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" *!* format "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ******************************************************************************** Function ctlGuidFromString(pcGuidString As String) Local ; m.lcGuid As String, ; m.lcGuidString As String m.lcGuid = "" *!* Strip brackets and hyphens m.lcGuidString = Chrtran(m.pcGuidString, "{-}", "") *!* Reorder GUID string chars m.lcGuid = ; + Substr(m.lcGuidString, 7, 2) ; + Substr(m.lcGuidString, 5, 2) ; + Substr(m.lcGuidString, 3, 2) ; + Left(m.lcGuidString, 2) ; + Substr(m.lcGuidString, 11, 2) ; + Substr(m.lcGuidString, 9, 2) ; + Substr(m.lcGuidString, 15, 2) ; + Substr(m.lcGuidString, 13, 2) ; + Right(m.lcGuidString, 16) *!* Convert bytes to decoded HexBinary m.lcGuid = Strconv(m.lcGuid, 16) Return m.lcGuid Endfunc ******************************************************************************** *!* Used just to check the other functions *!* StringUuid parameter of UuidToString: *!* Pointer to a pointer to the string into which *!* the UUID specified in the Uuid parameter will be placed. *!* UuidToString returns a string in the following format: *!* "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx" (lowercase) ******************************************************************************** Function ctlGuidToStringApi1(m.pcGuid As String) Local m.lnPointer As Integer m.lnPointer = 0 apiUuidToString(m.pcGuid, @m.lnPointer) Return Sys(2600, m.lnPointer, 36) Endfunc ******************************************************************************** *!* Used just to check the other functions ******************************************************************************** Function ctlGuidToStringApi2(m.pcGuid As String) Local ; m.lcGuidString As String, ; m.lcLen As Integer *!* Set up buffer: 39 chars * 2 (unicode) m.lcGuidString = Space(78) m.lcLen = 78 apiStringFromGUID2(m.pcGuid, @m.lcGuidString, m.lcLen) *!* Remove double null and convert from Unicode: Return Strconv(Left(m.lcGuidString, 76), 6) Endfunc ******************************************************************************** *!* Used just to check the other functions ******************************************************************************** Function ctlGuidFromStringApi(m.pcGuidString As String) Local ; m.lcUuid As String, ; m.lcGuidString As String *!* Strip brackets and hyphens m.lcGuidString = Chrtran(m.pcGuidString, "{-}", "") *!* Add hyphens m.lcGuidString = ; LEFT(m.lcGuidString, 8) ; + "-" ; + Substr(m.lcGuidString, 9, 4) ; + "-" ; + Substr(m.lcGuidString, 13, 4) ; + "-" ; + Substr(m.lcGuidString, 17, 4) ; + "-" ; + Right(m.lcGuidString, 12) m.lcUuid = Replicate(Chr(0xFF), 16) apiUuidFromString(m.lcGuidString, @m.lcUuid) Return m.lcUuid Endfunc ******************************************************************************** *!* END ctl32_functions ******************************************************************************** Function __BaseX( txVal, tcDom ) * Converts a number to a string representation of that number * tnVal - Number * tcDom - The domain of characters to be used * typical Domains are: * "01" - Binary * "0123456789" - Decimal * "0123456789abcdef" - Hex * "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - Base62 * "23456789ABCDEFGHJKLMNPRSTUVWXYZ" - No {01IOQ} - they might confuse a user. * If you want the result padded, use PADL() Local ; lnVal, ; lnDomSiz, ; lcRet, ; lnPosition, ; lnPlace If Vartype(txVal) = "N" If txVal < 0 Then txVal = txVal + 1 Endif lnVal = txVal lnDomSiz = Len(tcDom) * Humans get restless if the value zero is displayed as an empty string (blank). * The first char of the domain (generally 0) is normally used as a place holder, * but in the case of the value zero, it fills in to keep the peace. * This may have lead to the fall of Rome. If lnVal = 0 lcRet = Substr( tcDom, 1, 1 ) Else lcRet = '' Do While lnVal <> 0 lnDig = lnVal % lnDomSiz lnVal = Int( lnVal/lnDomSiz ) If txVal > 0 Then lcDig = Substr( tcDom, lnDig+1, 1 ) Else If lnDig = 0 Then lnDig = 16 Endif lcDig = Substr( tcDom, lnDig, 1 ) Endif lcRet = lcDig + lcRet Enddo Endif lxRet=lcRet Else * Convert it back to decimal lnVal = 0 lnPlace = 0 For lnPosition = Len(txVal) To 1 Step -1 lnVal = lnVal + (At( Substr(txVal,lnPosition,1), tcDom)-1) * (Len(tcDom)^lnPlace) lnPlace=lnPlace+1 Endfor lxRet = lnVal Endif Return lxRet Endfunc