Wilson WindowWare Tech Support

WinBatch WinBatch+Compiler WebBatch
Home | Tech Database | Tech BBS | White Papers | Purchase


Change Screen Resolution (in NT/95/98)

Keywords:      Screen Resolution   ENUM control settings

Question:

Do you know how to change screen resolution (eg 800x600) via Winbatch?

Answer:

There is no built in WinBatch function to allow you to change screen resolution on the fly. This does not mean it is not possible, it's just not supported.

Here is a script. I tested this one under NT. But I understand it works under 95/98 as well. It shows how to change screen resolutions on the fly.

;;;;;;;;;;;;;;;;;;;;;;;ENUM control settings;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Size of TDEVICEMODEA record: 156 Bytes
;Field offsets and sizes are:
offdmDeviceName =0 ;32
offdmSpecVersion =32 ;2
offdmDriverVersion =34 ;2
offdmSize =36 ;2
offdmDriverExtra =38 ;2
offdmFields =40 ;4
offdmOrientation =44 ;2
offdmPaperSize =46 ;2
offdmPaperLength =48 ;2
offdmPaperWidth =50 ;2
offdmScale =52 ;2
offdmCopies =54 ;2
offdmDefaultSource =56 ;2
offdmPrintQuality =58 ;2
offdmColor =60 ;2
offdmDuplex =62 ;2
offdmYResolution =64 ;2
offdmTTOption =66 ;2
offdmCollate =68 ;2
offdmFormName =70 ;32
offdmLogPixels =102 ;2
offdmBitsPerPel =104 ;4
offdmPelsWidth =108 ;4
offdmPelsHeight =112 ;4
offdmDisplayFlags =116 ;4
offdmDisplayFrequency =120 ;4
offdmICMMethod =124 ;4
offdmICMIntent =128 ;4
offdmMediaType =132 ;4
offdmDitherType =136 ;4
offdmICCManufacturer =140 ;4
offdmICCModel =144 ;4
offdmPanningWidth =148 ;4
offdmPanningHeight =152 ;4

;You have to create a binary buffer of 156 bytes size and i hope the 
;WinBatch function you use for that returns a pointer to the created buffer 
;than can be used with EnumDisplaySettings.

TDEVICEMODEA=BinaryAlloc(156)

;EnumDisplaySettings is a function exported by the user32.dll. There are 
;actually two versions, one for Unicode, one for ANSI strings (the 
;DEVICEMODE record contains several string fields). We need the one for 
;ANSI, which is named EnumDisplaySettingsA. 

UserDll=strcat(DirWindows(1),"USER32.DLL")

;The function has three 
;parameters (types pointer, integer, pointer) and returns an integer that is 
;interpreted as a boolean (0 is False, anything else is True). 




modeindex = 0
Selection=""
while 1
    returnvalue = DllCall(UserDll, LONG:"EnumDisplaySettingsA", LPNULL, LONG:modeindex, lpbinary:TDEVICEMODEA )
    IF returnvalue == 0 then break
    
    
    dmBitsPerPel       =BinaryPeek4(TDEVICEMODEA,offdmBitsPerPel)
    dmPelsWidth        =BinaryPeek4(TDEVICEMODEA,offdmPelsWidth)
    dmPelsHeight       =BinaryPeek4(TDEVICEMODEA,offdmPelsHeight)
    dmDisplayFlags     =BinaryPeek4(TDEVICEMODEA,offdmDisplayFlags)
    dmDisplayFrequency =BinaryPeek4(TDEVICEMODEA,offdmDisplayFrequency)
    
    
    line=strcat("W=",dmPelsWidth," H=",dmPelsHeight," Cbits=",dmBitsPerPel," Hz=",dmDisplayFrequency, " F=",dmDisplayFlags)
    if modeindex==0 then selection=line
    else selection=strcat(selection,@tab,line)
    modeindex = modeindex + 1
endwhile

newsetting=AskItemList("Choose Desired Setting",Selection,@tab,@unsorted,@single)
;parse selected setting
dmPelsWidth=       ItemExtract(2,ItemExtract(1,newsetting," "),"=")
dmPelsHeight=      ItemExtract(2,ItemExtract(2,newsetting," "),"=")
dmBitsPerPel=      ItemExtract(2,ItemExtract(3,newsetting," "),"=")
dmDisplayFrequency=ItemExtract(2,ItemExtract(4,newsetting," "),"=")
dmDisplayFlags=    ItemExtract(2,ItemExtract(5,newsetting," "),"=")

BinaryPoke4(TDEVICEMODEA,offdmBitsPerPel        ,dmBitsPerPel)      
BinaryPoke4(TDEVICEMODEA,offdmPelsWidth         ,dmPelsWidth)       
BinaryPoke4(TDEVICEMODEA,offdmPelsHeight        ,dmPelsHeight)      
BinaryPoke4(TDEVICEMODEA,offdmDisplayFlags      ,dmDisplayFrequency)    
BinaryPoke4(TDEVICEMODEA,offdmDisplayFrequency  ,dmDisplayFlags)

;Find selected buffer again (for NT)
modeindex = 0
Selection=""
while 1
    returnvalue = DllCall(UserDll, LONG:"EnumDisplaySettingsA", LPNULL, LONG:modeindex, lpbinary:TDEVICEMODEA )
    IF returnvalue == 0 
       Message("Res Change","Strange error occurred")
       exit
    endif
    
    
    dmBitsPerPel2       =BinaryPeek4(TDEVICEMODEA,offdmBitsPerPel)
    dmPelsWidth2        =BinaryPeek4(TDEVICEMODEA,offdmPelsWidth)
    dmPelsHeight2       =BinaryPeek4(TDEVICEMODEA,offdmPelsHeight)
    dmDisplayFlags2     =BinaryPeek4(TDEVICEMODEA,offdmDisplayFlags)
    dmDisplayFrequency2 =BinaryPeek4(TDEVICEMODEA,offdmDisplayFrequency)
    
    if dmBitsPerPel==dmBitsPerPel2 &&  dmPelsWidth==dmPelsWidth2  && dmPelsHeight==dmPelsHeight2 && dmDisplayFlags==dmDisplayFlags2 && dmDisplayFrequency==dmDisplayFrequency2
       ; we found our setting...
       break
    endif

    modeindex = modeindex + 1
endwhile

;End NT Fix


; set the field mask to determine fields to use for setting the display mode
DM_BITSPERPEL = 262144 ; 0x40000
DM_PELSWIDTH = 524288 ; 0x80000
DM_PELSHEIGHT = 1048576 ; 0x100000
DM_DISPLAYFLAGS = 2097152 ; 0x200000
DM_DISPLAYFREQUENCY = 4194304 ; 0x400000
dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY ; 0x7C0000 = 8126464 decimal

BinaryPoke4(TDEVICEMODEA, offdmFields, dmFields)
;BinaryPoke4(TDEVICEMODEA ,offdmBitsPerPel ,dmBitsPerPel);
;BinaryPoke4(TDEVICEMODEA ,offdmPelsWidth ,dmPelsWidth);
;BinaryPoke4(TDEVICEMODEA ,offdmPelsHeight ,dmPelsHeight);


CDS_DYNAMICONLY=0      ; Change current serrion only
CDS_UPDATEREGISTRY =1  ; Change and update registry
CDS_TEST =2            ; test only
changemode=CDS_UPDATEREGISTRY
returnvalue = DllCall(UserDll, LONG:"ChangeDisplaySettingsA", lpbinary:TDEVICEMODEA, LONG:changemode )

DISP_CHANGE_SUCCESSFUL=  0      ;The settings change was successful.
DISP_CHANGE_RESTART=     1  ;The computer must be restarted in order for the graphics mode to work.
DISP_CHANGE_FAILED=     -1  ;The display driver failed the specified graphics mode.
DISP_CHANGE_BADMODE=    -2  ;The graphics mode is not supported.
DISP_CHANGE_NOTUPDATED= -3      ;Unable to write settings to the registry.
DISP_CHANGE_BADFLAGS=   -4      ;An invalid set of flags was passed in.
DISP_CHANGE_BADPARAM=   -5  ; Bad parameters

switch returnvalue
     case 1
         line="The computer must be restarted in order for the graphics mode to work."
         break
     case 0
         line="The settings change was successful."
         break
     case -1
         line="The display driver failed the specified graphics mode."
         break
     case -2
         line="The graphics mode is not supported."
         break
     case -3
         line="Unable to write settings to the registry."
         break
     case -4
         line="An invalid set of flags was passed in."
         break
     case -5
         line="Bad parameters"
         break
     case returnvalue
         line="Unknown return code %returnvalue%"
         break
endswitch

if returnvalue==1
   if changemode!=CDS_UPDATEREGISTRY
       line=strcat(line,@crlf,"Because the Update Registry option was not in effect, no changes will be made")
       Message("Resolution Change",line)
       exit
   else
      Pause("Reboot machine",line)
      IntControl(67,0,0,0,0)
   endif
else
   Message("Resolution Change",line)
endif


;;;;;;;;;;;;;;;;;;;;;;

Article ID:   W13208
Filename:   Change Screen Resolution.txt