Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++ to MASM32

109 views
Skip to first unread message

Jack/Donna Shankle

unread,
Nov 8, 1999, 3:00:00 AM11/8/99
to
Hello,

GetTextMetrics, TextOut and SetTextAlign all use "windows.h". If I include
"windows.h" in the MASM32 program and assemble it, errors occur.
If I take "windows.h" out I get undefined errors on the three items above.
I know "windows.h" was written for C++ but how can I get a "windows.h"
that will assemble in MASM32? And is that what I want to do?????

Any help would be appreciated.

J. P. Shankle
jpsd...@digital.net


ccbrown

unread,
Nov 8, 1999, 3:00:00 AM11/8/99
to
Masm32 should include the file Windows.inc in your Include subdirectory of
the installation. This is what you need for assembler projects. Windows.h is
for C(++) compilers.
Steve R


Jack/Donna Shankle <jpsd...@digital.net> wrote in message
news:s2e21k...@corp.supernews.com...

Randall S Johnson

unread,
Nov 10, 1999, 3:00:00 AM11/10/99
to
You have to make sure you use the invoke commands correctly.
Below is an example provided in the samples directory of the MASM 6.11
package for accessing a DLL this is just an example there are 10 other
files in the directory required to compile and operate this program but
this should be illustrative of the problem you are addressing

;----------------------------------------------------------------------------;
;
SYSDATA.ASM ;
;----------------------------------------------------------------------------;
; Sample program that accesses the SYSINFO.DLL
functions. ;
;----------------------------------------------------------------------------;

.model small, pascal, nearstack
.286

?WINPROLOGUE = 1
include win.inc ; Converted from WINDOWS.H
include dll.inc ; SYSINFO.DLL definitions
include sysdata.inc ; equates for dialog controls

;----------------------------------------------------------------------------;
; Prototypes & External
Definitions ;
;----------------------------------------------------------------------------;

NPBYTE TYPEDEF NEAR PTR BYTE

WinMain PROTO PASCAL, hInstance:HANDLE, hPrevInstance:HANDLE,
lpszCmdLine:LPSTR, nCmdShow:SWORD
WndProc PROTO FAR PASCAL, :HWND, :WORD, :SWORD, :SDWORD
SetDlg PROTO, :HWND
SetKeyb PROTO, :HWND
SetTime PROTO, :HWND
int2hex PROTO, :WORD, :NPBYTE
SetItem PROTO, :HWND, :WORD, :WORD

extern __astart:proc ; When Windows load an app, it expects
astart
; to have the necessary start-up code. We get
; astart from APPENTRY.ASM

;----------------------------------------------------------------------------;
; Numeric
Equates ;
;----------------------------------------------------------------------------;

TIMER_SECS EQU 1000t ; timer interval: 1000 mill = 1
second
fNUMLOCK EQU 020h ; Flags within the Keyboard
Status word
fCAPLOCK EQU 040h ; that indicate different key
modes
fSHIFTS EQU 003h
fCONTROL EQU 004h


;----------------------------------------------------------------------------;
; Data
Segments ;
;----------------------------------------------------------------------------;

.const

szAppName SBYTE "SysData",0
szSysIcon SBYTE "SysIcon",0
szTooManyTimers SBYTE "Too many clocks or timers!",0

szError SBYTE "Error",0

szCoNotInst SBYTE "Not Found",0
szCoInst SBYTE "Found",0

szOff SBYTE "Off",0
szOn SBYTE "On",0

hex BYTE '0123456789ABCDEF' ; Table of hexadecimal
digits
; for int2hex function
ProcTable NPBYTE sz8086
NPBYTE sz80186
NPBYTE sz80286
NPBYTE sz80386
NPBYTE sz80486

sz8086 SBYTE "8086",0
sz80186 SBYTE "80186",0
sz80286 SBYTE "80286",0
sz80386 SBYTE "80386",0
sz80486 SBYTE "80486",0

.data

HexValue BYTE "xxxxh",0
Initialized BYTE 0

;----------------------------------------------------------------------------;
; Code
Segment ;
;----------------------------------------------------------------------------;

.code

;----------------------------------------------------------------------------;
;
WinMain ;
;----------------------------------------------------------------------------;
;
;
; Main routine called by Windows in program start. If no previous
instances, ;
; sets up a window class and registers it, then sets up the message
loop. ;
;
;
;----------------------------------------------------------------------------;

WinMain PROC, hInstance:HANDLE, hPrevInstance:HANDLE,
lpszCmdLine:LPSTR, nCmdShow:SWORD
LOCAL msg:MSG, wndclass:WNDCLASS

; Local variables: msg: message to be used in the message loop
; wndclass: temp. to store window class
; x,y Start-Client: Size of Initial Window
;
;--- Check for previous instances
;
.IF (hPrevInstance == 0)

lea di, wndclass ; because we use a NEARSTACK,
ASSUME di:PTR WNDCLASS ; ss=ds

mov WORD PTR [di].lpfnWndProc, LROFFSET WndProc
mov WORD PTR [di].lpfnWndProc+2, SEG WndProc

mov [di].cbWndExtra, DLGWINDOWEXTRA

xor ax,ax
mov [di].style,ax
mov [di].cbClsExtra, ax

INVOKE LoadIcon, hInstance, ADDR szSysIcon
mov [di].hIcon, ax

mov ax, hInstance
mov [di].hInstance, ax

INVOKE LoadCursor, NULL, IDC_ARROW
mov [di].hCursor, ax

mov [di].hbrBackground, COLOR_WINDOW +1

xor ax, ax
mov WORD PTR [di].lpszMenuName, ax
mov WORD PTR [di].lpszMenuName+2, ax

mov WORD PTR [di].lpszClassName, OFFSET szAppName
mov WORD PTR [di].lpszClassName+2, ds

INVOKE RegisterClass, di
.IF (ax == 0)
mov ax, FALSE
jmp doRet
.ENDIF

ASSUME di:NOTHING

.ENDIF ;--- End of IF (hPrevInstance == 0)

INVOKE CreateDialog, hInstance, ADDR szAppName, 0, NULL
mov si, ax
INVOKE ShowWindow, si, nCmdShow

;---- Create Timer for Window

INVOKE SetTimer, si, 1, TIMER_SECS, NULL
.IF (ax == 0)
INVOKE MessageBox, si,ADDR szTooManyTimers,
ADDR szAppName,
MB_ICONEXCLAMATION OR MB_OK
mov ax, FALSE
INVOKE PostQuitMessage, 0 ; Quit.
.ENDIF

;---- Message Loop

.WHILE TRUE

INVOKE GetMessage, ADDR msg, NULL, 0, 0

.BREAK .IF (ax == 0)

INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg

.ENDW

mov ax, msg.wParam
doRet:
ret

WinMain ENDP


;----------------------------------------------------------------------------;
;
SetTime ;
;
;
; Reads the System Time with GetSysTime, sets up the Dialog Item
TIME_TEXT ;
; with the resulting string. Then does the same for
DATE_TEXT. ;
;----------------------------------------------------------------------------;

SetTime PROC, hDlg:HWND

INVOKE GetSysTime
INVOKE SetDlgItemText, hDlg, TIME_TEXT, dx::ax
INVOKE GetSysDate
INVOKE SetDlgItemText, hDlg, DATE_TEXT, dx::ax

ret
SetTime ENDP


;----------------------------------------------------------------------------;
;
SetKeyb ;
;
;
; Assumes DI has the keyboard status. Gets the control's text into
buffer. ;
; If the control's status has changed (if buffer+1 is not what it would
be ;
; set to) then set it to On or Off, otherwise
return ;
;----------------------------------------------------------------------------;

SetItem PROC, hDlg:HWND, item:WORD, flag:WORD
LOCAL buffer[3]:BYTE

INVOKE GetDlgItemText, hDlg, item, ADDR buffer, 3

mov bx, di
and bx, flag
.IF bx
.IF (byte ptr buffer+1 != 'n') ; 'n' means we have 'On'
mov bx, OFFSET szOn
.ELSE
jmp doRet
.ENDIF
.ELSE
.IF (byte ptr buffer+1 != 'f') ; 'f' means we have 'Off'
mov bx, OFFSET szOff
.ELSE
jmp doRet
.ENDIF
.ENDIF
INVOKE SetDlgItemText, hDlg, item, ds::bx

doRet:
ret

SetItem ENDP


;----------------------------------------------------------------------------;
;
SetKeyb ;
;
;
; Reads the keyboard status with GetSysInfo, then uses SetItem to set
the ;
; appropiate controls in the dialog
box. ;
;----------------------------------------------------------------------------;

SetKeyb PROC, hDlg:HWND

INVOKE GetSysInfo
mov es, dx
mov si, ax
ASSUME SI:PTR SYSINFO
mov di, es:[si].wKbStatus
INVOKE SetItem, hDlg, NUMLOCK,fNUMLOCK
INVOKE SetItem, hDlg, CAPLOCK,fCAPLOCK
INVOKE SetItem, hDlg, CONTROL,fCONTROL
INVOKE SetItem, hDlg, SHIFTS, fSHIFTS
ASSUME SI:NOTHING

ret
SetKeyb ENDP

;----------------------------------------------------------------------------;
;
SetDlg ;
;
;
; Reads the System Time with GetSysTime, sets up the Dialog Item
TIME_TEXT ;
; with the resulting string. Then does the same for DATE_TEXT. Then gets
the ;
; other system information with GetSysInfo and sets the appropiate
Dialog ;
; Items. Note that KEYBSTAT and VIDEOMODE take the hex of the value
returned.;
; Since ES is not guaranteed to be preserved, have to restore it after
every ;
; SetDlgItemInt or Text. A table is used to look up the processor
type. ;
;----------------------------------------------------------------------------;

SetDlg PROC, hDlg:HWND

INVOKE SetTime, hDlg
INVOKE SetKeyb, hDlg

INVOKE GetSysInfo
mov di, dx
mov si, ax

ASSUME SI:PTR SYSINFO

lea ax, [si].szWinVer
INVOKE SetDlgItemText, hDlg, WINVERSION, di::ax
lea ax, [si].szDOSVer
INVOKE SetDlgItemText, hDlg, DOSVERSION, di::ax
lea ax, [si].szROM
INVOKE SetDlgItemText, hDlg, ROMBIOS, di::ax

mov es, di
mov al, es:[si].cFloppy
INVOKE SetDlgItemInt, hDlg, FLOPPIES, al, FALSE

mov es, di
mov bl, es:[si].cVidMode
INVOKE int2hex, bl, ADDR HexValue
INVOKE SetDlgItemText, hDlg, VIDEOMODE, ADDR HexValue

mov es, di
.IF es:[si].bCoproc
mov ax, OFFSET szCoInst
.ELSE
mov ax, OFFSET szCoNotInst
.ENDIF
INVOKE SetDlgItemText, hDlg, COPROC, ds::ax

mov es, di
mov bl, es:[si].cProcType
.IF (bl < 5)
xor bh, bh
shl bx, 1
mov ax, ProcTable[bx]
.ELSE
mov ax, OFFSET szError
.ENDIF
INVOKE SetDlgItemText, hDlg, PROCTYPE, ds::ax

ASSUME SI:NOTHING

ret

SetDlg ENDP

;----------------------------------------------------------------------------;
; int2hex
; Converts a WORD into its hexadecimal representation.
; Based on Chapter 4 of the MASM Programmer's guide
;----------------------------------------------------------------------------;

int2hex PROC NEAR USES ax bx si, number:WORD, string:NPBYTE

mov bx, OFFSET hex ; load table address
mov si, string

mov ax, number ; load value to convert
shr ax, 12 ; shift right to get into table index
and ax, 0000Fh ; remove all but least-significant byte
xlat ; translate
mov [si], al ; store as last byte

mov ax, number ; load value to convert
shr ax, 8 ; shift right to get into table index
and ax, 0000Fh ; remove all but least-significant byte
xlat ; translate
mov [si+1], al ; store as third to last byte

mov ax, number ; load value to convert
shr ax, 4 ; shift right to get into table index
and ax, 0000Fh ; remove all but least-significant byte
xlat ; translate
mov [si+2], al ; store as second to last byte

mov ax, number ; load value to convert
and ax, 0000Fh ; remove all but least-significant byte
xlat ; translate
mov [si+3], al ; store as last byte in string

ret

int2hex ENDP


;----------------------------------------------------------------------------;
;
WndProc ;
;
;
; Because this is a Dialog Box/Window, we cannot intercept the
WM_CREATE ;
; message to set up the initial values of the Dialog Box. We have to
wait for;
; the timer or the keyboard status to change to set values. Initialized
is a ;
; flag to determine if the other values need to be
set. ;
; If we get a timer message, set the time and
date. ;
; If we get a KEYDOWN or KEYUP message, set the Keyboard
Status ;
; If we get a WININICHANGE, SETFOCUS, or SYSKEYUP, some data could
change. ;
; Reset the dialog
items ;
; A Close Window will get us
out. ;
;----------------------------------------------------------------------------;

WndProc PROC FAR PASCAL, hWnd:HWND, iMessage:WORD, wParam:SWORD,
lParam:SDWORD
; Windows gives us: the handle of the Window, the Message ID,
; and two parameters for the message


.IF (iMessage == WM_TIMER)
.IF Initialized
INVOKE SetTime, hWnd
.ELSE
mov Initialized, TRUE
INVOKE SetDlg, hWnd
.ENDIF

.ELSEIF (iMessage == WM_KEYDOWN) || (iMessage == WM_KEYUP)
.IF Initialized
INVOKE SetKeyb, hWnd
.ELSE
mov Initialized, TRUE
INVOKE SetDlg, hWnd
.ENDIF

.ELSEIF (iMessage == WM_SETFOCUS) || (iMessage == WM_SYSKEYUP)\
|| (iMessage == WM_WININICHANGE)
INVOKE SetDlg, hWnd
jmp doDefault

.ELSEIF (iMessage==WM_DESTROY)
INVOKE KillTimer, hWnd, 1
INVOKE PostQuitMessage, 0

.ELSE
doDefault:
INVOKE DefWindowProc, hWnd, iMessage, wParam,lParam
jmp doRet

.ENDIF

mov ax, 0
cwd
doRet:
ret

WndProc ENDP


END __astart ; so that the code of the application will
; start with the Windows start-up code

D. Speir

unread,
Nov 12, 1999, 3:00:00 AM11/12/99
to
You should be able to get a working copy of the windows.inc
file at,
http://members.xoom.com/Iczel/
If you get any errors with this inc file, you can usually trace
them to spelling or declaration ambiguities that can be fixed.
Although you might just plain use an API or constant that's
not declared in a given inc file. In that case you will have to
look it up in your C compiler's api help and then write the asm
inc section yourself to be added to your windows.inc file.

0 new messages