Saturday, June 13, 2026

Multiple File Selection Dialog Box for FoxPro / Visual FoxPro

 PROCEDURE SelectMultipleImages

PARAMETERS laFiles


DO declare


#DEFINE OPENFILENAME_SIZE  76  && set to 88 for W2K


LOCAL lcBuffer, loFilter, loTitlebar, loFilename, loFilenameRet,;

loDefExt, loStartDir, lnErrorCode


* dialog title

loTitlebar = CreateObject("PChar", "Open a database file")


* file types filter

loFilter = CreateObject("PChar",;

    "Image Files (*.bmp;*.jpg;*.jpeg;*.gif)" + Chr(0) + ;

    "*.bmp;*.jpg;*.jpeg;*.gif")



* default extension, in case if user type a name with no extension

loDefExt = CreateObject("PChar", "DBC")


* suggest a file name or put just an empty string

loFilename = CreateObject("PChar", Padr("test.dbc", 250,Chr(0)))


* a space for file name to be returned

loFilenameRet = CreateObject("PChar", Repli(Chr(0),250))


* initial directory displayed in the dialog

loStartDir = CreateObject("PChar", SYS(5)+SYS(2003))


* configuration flags

#DEFINE OFN_HIDEREADONLY     0x4

#DEFINE OFN_NOCHANGEDIR      0x8

#DEFINE OFN_PATHMUSTEXIST    0x800

#DEFINE OFN_FILEMUSTEXIST    0x1000

#DEFINE OFN_ALLOWMULTISELECT 0x200

#DEFINE OFN_EXPLORER         0x80000

#DEFINE OFN_DONTADDTORECENT  0x2000000


lnFlags = OFN_PATHMUSTEXIST + OFN_FILEMUSTEXIST + ;

          OFN_HIDEREADONLY + OFN_NOCHANGEDIR + ;

          OFN_ALLOWMULTISELECT + OFN_EXPLORER


* assembling the OPENFILENAME structure

lcBuffer = num2dword(OPENFILENAME_SIZE) +;

num2dword(GetActiveWindow()) +;

num2dword(0) +;

num2dword(loFilter.GetAddr()) +;

num2dword(0) + num2dword(0) + num2dword(1) +;

num2dword(loFilename.GetAddr()) +;

num2dword(loFilename.GetAllocSize()) +;

num2dword(loFilenameRet.GetAddr()) +;

num2dword(loFilenameRet.GetAllocSize()) +;

num2dword(loStartDir.GetAddr()) +;

num2dword(loTitlebar.GetAddr()) +;

num2dword(lnFlags) +;

num2dword(0) +;

num2dword(loDefExt.GetAddr()) +;

num2dword(0) + num2dword(0) + num2dword(0)


* creating an Open dialog box

IF GetOpenFileName(@lcBuffer) = 0

lnErrorCode = CommDlgExtendedError()

IF lnErrorCode <> 0

? "Error code:", lnErrorCode

ELSE

* the Cancel button selected

ENDIF

RETURN null

ELSE

    * Read the null-separated string data from the buffer

    lcSelectedData = loFilename.GetValue()


    * Trim trailing nulls

    lcSelectedData = LEFT(lcSelectedData, AT(CHR(0)+CHR(0), lcSelectedData) - 1)


    * Replace nulls with delimiter for parsing

    lcSelectedData = STRTRAN(lcSelectedData, CHR(0), "|")


    * Split into array

    DIMENSION laFiles[GETWORDCOUNT(lcSelectedData,"|")]

    FOR i = 1 TO ALEN(laFiles)

        laFiles[i] = GETWORDNUM(lcSelectedData,i,"|")

    ENDFOR


    * If multiple files: first entry is directory, rest are filenames

    IF ALEN(laFiles) > 1

    lcPath = ADDBS(laFiles[1])    

    FOR i = 2 TO ALEN(laFiles)        

    laFiles[i-1] = lcPath + laFiles[i]

    && overwrite with full path    

    ENDFOR    

    DIMENSION laFiles[ALEN(laFiles)-1]       && shrink array to remove folder entry    

    ENDIF


* RETURN @laFiles

    * Display results

    *FOR i = 1 TO ALEN(laFiles)

    *    ? "Selected File " + TRANSFORM(i) + ": " + laFiles[i]

    *ENDFOR

ENDIF


* end of main


PROCEDURE declare

DECLARE INTEGER GetOpenFileName IN comdlg32 STRING @lpofn

DECLARE INTEGER GetActiveWindow IN user32

DECLARE INTEGER GlobalFree IN kernel32 INTEGER hMem

DECLARE INTEGER CommDlgExtendedError IN comdlg32


DEFINE CLASS PChar As Custom

hMem=0


PROCEDURE  Init (lcString)

THIS.SetValue (lcString)


PROCEDURE Destroy

THIS.ReleaseString


FUNCTION GetAddr  && returns a pointer to the string

RETURN THIS.hMem


FUNCTION GetValue && returns string value

LOCAL lnSize, lcBuffer

lnSize = THIS.getAllocSize()

lcBuffer = SPACE(lnSize)

IF THIS.hMem <> 0

DECLARE RtlMoveMemory IN kernel32 As Heap2Str;

STRING @, INTEGER, INTEGER

= Heap2Str (@lcBuffer, THIS.hMem, lnSize)

ENDIF

RETURN lcBuffer


FUNCTION GetAllocSize  && returns allocated memory size (string length)

DECLARE INTEGER GlobalSize IN kernel32 INTEGER hMem

RETURN Iif(THIS.hMem=0, 0, GlobalSize(THIS.hMem))


PROCEDURE SetValue(lcString) && assigns new string value

#DEFINE GMEM_FIXED   0

THIS.ReleaseString


DECLARE INTEGER GlobalAlloc IN kernel32 INTEGER, INTEGER

DECLARE RtlMoveMemory IN kernel32 As Str2Heap;

INTEGER, STRING @, INTEGER


LOCAL lnSize

lcString = lcString + Chr(0)

lnSize = Len(lcString)

THIS.hMem = GlobalAlloc (GMEM_FIXED, lnSize)

IF THIS.hMem <> 0

= Str2Heap (THIS.hMem, @lcString, lnSize)

ENDIF


PROCEDURE ReleaseString  && releases allocated memory

IF THIS.hMem <> 0

DECLARE INTEGER GlobalFree IN kernel32 INTEGER

= GlobalFree (THIS.hMem)

THIS.hMem = 0

ENDIF

ENDDEFINE


FUNCTION buf2word(lcBuffer)

RETURN Asc(SUBSTR(lcBuffer, 1,1)) + ;

       Asc(SUBSTR(lcBuffer, 2,1)) * 256


FUNCTION num2dword(lnValue)

#DEFINE m0  256

#DEFINE m1  65536

#DEFINE m2  16777216

IF lnValue < 0

lnValue = 0x100000000 + lnValue

ENDIF

LOCAL b0, b1, b2, b3

b3 = Int(lnValue/m2)

b2 = Int((lnValue - b3*m2)/m1)

b1 = Int((lnValue - b3*m2 - b2*m1)/m0)

b0 = Mod(lnValue, m0)

RETURN Chr(b0)+Chr(b1)+Chr(b2)+Chr(b3)  

Thursday, April 9, 2026

Comdlg32 OCX - License is not registered for use

Need to add the following registry key in Windows Registry to resolve the licensing issue.

REGEDIT4

[HKEY_CLASSES_ROOT\Licenses\DB4C0D00-400B-101B-A3C9-08002B2F49FB]

@="mgkgtgnnmnmninigthkgogggvmkhinjggnvm"


Tuesday, May 9, 2023

Crystal Report Runtime Installation Error 1935

Open your registry editor, find 

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control

Create Or Change (if exist)  RegistrySizeLimit's(REG_DWORD) value to “FFFFFFFF”

And Restart PC. (Without restart changes will not work)


Friday, April 14, 2023

Hello Everyone,

I am excited to offer my Visual FoxPro Project Maintenance/Updation Service. I can work with any version of the Visual FoxPro and provide the following features:

* Identify and fix any programming bugs in your applications.

* Upgrade your applications to .Net projects.

* Seamlessly migrate your Visual FoxPro's native database to other databases, such as SQL Server, MySQL, PostgreSQL, and more.

* Facilitate the migration of your database to the cloud, making it easily accessible for remote work via the Internet.

I am confident that my expertise in Visual FoxPro will add value to your business operations, and I look forward to working with you.


for more information contact

Skype: kalpesh2804

email : kalpesh@kalpesh.biz, kalpesh2804@yahoo.com

WhatsApp: +91 98 98 29 62 36

#VisualFoxPro #VisualFoxProSupport #FoxProDeveloper #FoxPro #FoxProSupport

Friday, November 8, 2019

Send Ctrl-Alt-Del to nested RDP session


eg.
PC - A  = Its your Own Computer
PC - B  = RDP  PC - 1
PC - C =  RDP PC - 2 (Inside RDP PC1)

Here's the scenario: I Remote Desktop from Computer A to Computer B and from Computer B to Computer C.

(1) I want to send Ctrl+Alt+Del to Computer A, I type Ctrl+Alt+Del from Computer A

(2)  want to send Ctrl+Alt+Del to Computer B, I type Ctrl+Alt+End  inside Computer B

(3) If I want to send Ctrl+Alt+Del to Computer C, I open the On-Screen Keyboard on Computer C and use it to type Ctrl+Alt+End, which sends Ctrl+Alt+Del to Computer C

OR  

If I want to send Ctrl+Alt+Del to Computer C, I type Shift+Ctrl+Alt+End  inside Computer C.