Manipulating the Windows Clipboard with DOS
We can work with the clipboard through the Multiplex interrupt, interrupt 2Fh service 17h.
We must check the use of this service before we can use it. To check it, call service 1700h. If 1700h returned, then error has occurred.
We must Open the clipboard to be able to use it. Once opened, we can:
- Get size of contents - returns the length in increments of 32. If the text is of length 55, then this will return 64.
- Clear the contents of the clipboard
- Get contents of the clipboard
- Put contents in to the clipboard
Then we most close it.
To use this code in a WinXP environment, you must first run NTOLDAPP.COM (NTOLDAPP.DLL) found here or here.
See below for a stripped down Basic version.
See V.01 Number 2 of DHmag for a DOS program to send a text file to the clipboard.
See this page for a TSR that uses the Windows clipboard.
You can also get and put graphics with these functions in Windows Bitmap format.
See the following line in the code below:
#define FRMT_BITMAP 2 // format of 2 = Windows Bitmap
#include "dos.h"
#define FRMT_TEXT 1
#define FRMT_BITMAP 2
int retcode;
unsigned int thisseg, thisoff, sizecnts;
unsigned char buffer[500];
void far *mptr = buffer;
int chkclipbrd();
int openclipbrd();
int closeclipbrd();
int clearclipbrd();
int getsizeclipbrd();
int getclipbrddata(unsigned dataseg, unsigned buffer);
int putclipbrddata(unsigned dataseg, unsigned buffer, unsigned bufsize);
int main(int argc, char *argv[]) {
printf("\nSmall example on communicating with the Windows clipboard.\n");
if (chkclipbrd() == 0) {
printf("\nError with clipboard.");
return -1;
}
openclipbrd();
sizecnts = getsizeclipbrd();
printf("\nThe current size of the clipboard contents: ");
printf("%i", sizecnts);
thisseg = FP_SEG(mptr);
thisoff = FP_OFF(mptr);
if (getclipbrddata(thisseg, thisoff) != 0) {
buffer[sizecnts] = '\0';
printf("\nThe current contents of the clipboard:\n\n");
printf("%s", buffer);
} else
printf("\n\nThe clipboard is empty\n");
clearclipbrd();
strcpy(buffer, "Forever Young Software");
printf("\nPutting 'Forever Young Software' in to the clipboard\n");
thisseg = FP_SEG(mptr);
thisoff = FP_OFF(mptr);
sizecnts = strlen(buffer);
putclipbrddata(thisseg, thisoff, sizecnts);
closeclipbrd();
return 0;
}
int chkclipbrd() {
_asm {
mov ax,1700h
int 2Fh
mov retcode,ax
}
if (retcode == 0x1700)
return 0;
else
return retcode;
}
int openclipbrd() {
_asm {
mov ax,1701h
int 2Fh
mov retcode,ax
}
return retcode;
}
int closeclipbrd() {
_asm {
mov ax,1708h
int 2Fh
mov retcode,ax
}
return retcode;
}
int clearclipbrd() {
_asm {
mov ax,1702h
int 2Fh
mov retcode,ax
}
return retcode;
}
int getsizeclipbrd() {
_asm {
mov ax,1704h
mov dx,FRMT_TEXT
int 2Fh
mov retcode,ax
}
return retcode;
}
int getclipbrddata(unsigned dataseg, unsigned buffer) {
_asm {
mov ax,1705h
mov es,dataseg
mov bx,buffer
mov dx,FRMT_TEXT
int 2Fh
mov retcode,ax
}
return retcode;
}
int putclipbrddata(unsigned dataseg, unsigned buffer, unsigned bufsize) {
_asm {
push si
mov ax,1703h
mov es,dataseg
mov bx,buffer
mov dx,FRMT_TEXT
mov cx,bufsize
xor si,si
int 2Fh
pop si
mov retcode,ax
}
return retcode;
}
Basic version
DECLARE FUNCTION ClipClose% ()
DECLARE FUNCTION ClipOpen% ()
DECLARE SUB ClipGetData (ClipSize%, ClipContents$)
DECLARE SUB ClipGetDataSize (ClipSize%)
' Remember to include the /I parameter at the command line
'$INCLUDE: 'qb.bi'
DIM ClipSize%, ClipContents$
DIM SHARED Regs AS RegType
DIM SHARED RegsX AS RegTypeX
CLS
IF ClipOpen% <> 0 THEN
PRINT "The Clipboard has been opened."
END IF
CALL ClipGetDataSize(ClipSize%)
PRINT
PRINT "The Clipboard holds"; ClipSize%; "bytes of information."
CALL ClipGetData(ClipSize%, ClipContents$)
PRINT
PRINT "ClipContents$="; ClipContents$; "*END"
IF ClipClose% <> 0 THEN
PRINT : PRINT "The Clipboard has been closed."
END IF
' 1 if successful, 0 if failed
'
FUNCTION ClipClose%
Regs.ax = &H1708
CALL INTERRUPT(&H2F, Regs, Regs)
ClipClose% = Regs.ax
END FUNCTION
SUB ClipGetData (ClipSize%, ClipContents$)
ClipContents$ = SPACE$(ClipSize%) + CHR$(0)
RegsX.ax = &H1705
RegsX.dx = &H1 'data type held in Clipboard = text
RegsX.es = VARSEG(ClipContents$)
RegsX.bx = SADD(ClipContents$)
CALL INTERRUPTX(&H2F, RegsX, RegsX)
END SUB
SUB ClipGetDataSize (ClipSize%)
Regs.ax = &H1704
Regs.dx = &H1 'data type = text
CALL INTERRUPT(&H2F, Regs, Regs)
ClipSize% = Regs.ax
END SUB
' 1 if successful, 0 if failed'
'
FUNCTION ClipOpen%
Regs.ax = &H1701
CALL INTERRUPT(&H2F, Regs, Regs)
ClipOpen% = Regs.ax
END FUNCTION