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:
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

/*****************************************************************************************
   This is a small demo on how to communicate with the Windows clipboard.
   This only works in a Windows DOS session, not in True DOS.

   - Compile in the medium model
*/

#include "dos.h"

#define FRMT_TEXT   1     // format of 1 = text
#define FRMT_BITMAP 2     // format of 2 = Windows Bitmap

         int  retcode;
unsigned int  thisseg, thisoff, sizecnts;
unsigned char buffer[500];   // make sure large enough

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();    // open the clipboard interface (allow us to use it)

  sizecnts = getsizeclipbrd();   // in increments of 32  (2 paragraphs)
  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();  // clear the clipboard contents

  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(); // close the clipboard interface (don't allow us to use it)

  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