/**************************************************************************** Skeleton Win32 GUI app, written in Sphinx C-- by Barry Kauler, Aug. 2002 www.goosee.com/cmm/ To compile, need "win1.c--" (this file), "win1.rc", "star.ico" in same directory, and "c--.exe" in same directory or in DOS path. The "#includepath" has path of the Windows header files. Note 1: due to option "ia" -- "int" is an instruction so "int" can no longer be used as a datatype --use "long" instead. To compile, just type "c-- win1" -- that's it. Note 2: This example is not the "nicest" C code. I ported a Win32 skeleton application written in Microsoft assembler (MASM) with minimal modifications -- shows how easy to port. ****************************************************************************/ #pragma option w32 //create Windows GUI EXE. #pragma option J0 //no startup code. #pragma option dbg //create debug information (separate .tds file). #pragma option lst //generate listing file. #pragma option w //enable warning. #pragma option 3 //386 CPU. #includepath "c:\progra~2\c--\lib\win" #include "windef.h--" #include "winbase.h--" //kernel32.dll #include "wingdi.h--" //gdi32.dll #include "winuser.h--" //user32.dll #include "commctrl.h--" //comctl32.dll #include "commdlg.h--" //comdlg32.dll #include "shellapi.h--" //shell32.dll #pragma option ia //no need "$" or "asm" for inline asm. //...note, /ia option placed after headers, as some use "int" datatype. #include "win1.rc" //resource file. //.................................................. // Variables used by main()... dword g_hinst=0; dword g_hwnd=0; struct WNDCLASS s1; struct MSG s2; char szcommandline[256]; //used by WM_LBUTTONDBLCLK, to launch editor. dword g_hcrosshair=0; //handle for cross-hair cursor. dword g_hnormcursor=0; //normal cursor. dword g_hbusycursor=0; //busy cursor. dword g_hwhitebrush=0; //handle of a brush. dword g_hblackbrush=0; // / dword g_hgraybrush=0; // / dword g_hstandardbrush=0; // / dword g_cstandardbrush=0; //RGB color, not a handle, for standard window background. char szTitleName=" WIN1"; char szClassName="WIN1"; //variables used by WNDproc()... char szaboutstr="Simple Win32 GUI app written in Sphinx C--"; char sztitlestr="Barry Kauler, Aug. 2002"; //.................................................. main() { GetModuleHandle(NULL); //startup code. mov g_hinst,eax // / GetCommandLine(); // / lstrcpy(#szcommandline,EAX); // / //...this example is educational rather than "nicest" C code. //here is above code tidied up: //g_hinst=GetModuleHandle(NULL); //lstrcpy(#szcommandline,GetCommandLine()); // initialize the WndClass structure... mov s1.style,CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS mov s1.lpfnWndProc,#WNDproc mov s1.cbClsExtra,0 mov s1.cbWndExtra,0 mov eax,g_hinst mov s1.hInstance,eax //...for the exercise, let's tidy this up too: //s1.style=CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; //s1.lpfnWndProc=#WNDproc; //s1.cbClsExtra=s1.cbWndExtra=0; //s1.hInstance=g_hinst; // LoadIcon(NULL, IDI_APPLICATION); //loads default icon. //let's load a custom icon.... LoadIcon(g_hinst,470); //icon id in eve.rc mov s1.hIcon,eax //to be able to change cursors, think need to set this param to 0... //(also see further down) LoadCursor(NULL,IDC_ARROW); mov s1.hCursor, eax mov g_hnormcursor,eax GetSysColor(COLOR_WINDOW); //returns RGB for window background mov g_cstandardbrush,eax GetSysColorBrush(COLOR_WINDOW); //returns brush for window background. mov g_hstandardbrush,eax //...note, not allowed to use a brush for a systems color to register //a window class, but can use the color-index, ex COLOR_WINDOW //(refer SetClassLongA() func) GetStockObject(BLACK_BRUSH); mov g_hblackbrush,eax GetStockObject(LTGRAY_BRUSH); //light grey. mov g_hgraybrush,eax GetStockObject(WHITE_BRUSH); mov g_hwhitebrush,eax mov s1.hbrBackground,eax //COLOR_WINDOW + 1 mov s1.lpszMenuName,#szClassName mov s1.lpszClassName,#szClassName RegisterClass(#s1); test eax,eax jnz NOT_END //end_loop //exit if eax=0. jmp end_loop NOT_END: CreateWindowEx(0,#szClassName,#szTitleName,WS_OVERLAPPEDWINDOW,5,5,300,200,0,0,g_hinst,0); //note i had x/y = CW_USEDEFAULT & width/height =CW_USEDEFAULT, //i now have 5,5,300,200 test eax,eax jz end_loop //exit if eax=0. mov g_hwnd,eax ShowWindow(g_hwnd,SW_SHOWNORMAL); UpdateWindow(g_hwnd); //load this also, for use later... LoadCursor(NULL,IDC_CROSS); //cross-hair. mov g_hcrosshair,eax LoadCursor(NULL,IDC_WAIT); //hour-glass cursor. mov g_hbusycursor,eax msg_loop: GetMessage(#s2,0,0,0); or eax,eax //cmp eax,0 je end_loop TranslateMessage(#s2); DispatchMessage(#s2); jmp msg_loop end_loop: ExitProcess(s2.wParam); } //.......................................................... // main callback procedure dword WNDproc(dword hwnd,wmsg,wparam,lparam) { struct PAINTSTRUCT s3; dword hdc; dword hbrushsaved; switch(wmsg) { case WM_DESTROY: //DestroyWindow() generates this. PostQuitMessage(0); //...main() will get this and call ExitProcess() (see above). break; case WM_COMMAND: IF(lparam==0) { //a menu-item has been selected... switch(wparam) { case IDM_ABOUT: MessageBox(g_hwnd,#szaboutstr,#sztitlestr,MB_OK); break; case IDM_EXIT: DestroyWindow(g_hwnd); //NOTE this will post WM_DESTROY msg (see above). break; } } break; case WM_PAINT: hdc=BeginPaint(g_hwnd,#s3); hbrushsaved=SelectObject(hdc,g_hgraybrush); Ellipse(hdc,5,5,275,125); SelectObject(hdc,hbrushsaved); EndPaint(g_hwnd,#s3); default: DefWindowProc(hwnd,wmsg,wparam,lparam); jmp short getout //...note could have "return;" here but want common exit point. } xor eax,eax //return 0 if have processed msg here. getout: } //.....................................................