home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: InfoMgt / InfoMgt.zip / calendr1.zip / CALENDA2.ASM < prev    next >
Assembly Source File  |  1990-10-03  |  14KB  |  327 lines

  1.               PAGE     60, 120
  2.               TITLE    CALENDA2 - PM Calendar Function
  3.  
  4. ;------------------------------------------------------------------------------
  5. ;
  6. ;                      Copyright (c) 1990  BEST SOFTWARE
  7. ;
  8. ;
  9. ;               CALENDA2.ASM - PM Calendar Program (part 2 of 2)
  10. ;
  11. ;------------------------------------------------------------------------------
  12.               PAGE
  13.               .MODEL   SMALL, PASCAL
  14.  
  15. ;------------------------------------------------------------------------------
  16. ;  External references
  17. ;------------------------------------------------------------------------------
  18.  
  19.               EXTRN    convert_num_1: PROC
  20.  
  21. ;------------------------------------------------------------------------------
  22. ;  Include files
  23. ;------------------------------------------------------------------------------
  24.  
  25.               .SALL
  26.               .XLIST
  27.               INCLUDE  common.inc
  28. INCL_DOS      EQU      1
  29. INCL_WIN      EQU      1
  30. INCL_GPI      EQU      1
  31.               INCLUDE  os2.inc
  32.               .LIST
  33.  
  34. PARAMETERS    STRUC
  35. parm_month    DW       ?
  36. parm_year     DW       ?
  37. PARAMETERS    ENDS
  38.               PAGE
  39. ;------------------------------------------------------------------------------
  40. ;  Data and constants
  41. ;------------------------------------------------------------------------------
  42.  
  43.               .CONST
  44.  
  45. normal_year   DB       31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  46. leap_year     DB       31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  47.  
  48. two_digits    DB       '99'
  49.               PAGE
  50.               .286
  51.               .CODE
  52. ;------------------------------------------------------------------------------
  53. ;  Window procedure for 'CALENDAR' class
  54. ;------------------------------------------------------------------------------
  55.  
  56. calendar_proc PROC     FAR USES ds,                                            \
  57.                        hwnd: DWORD, msg: WORD, mp1: DWORD, mp2: DWORD
  58.  
  59.               LOCAL    parm_pointer: FAR PTR,                                  \
  60.                        hps: DWORD,                                             \
  61.                        rectl [SIZ RECTL]: BYTE,                                \
  62.                        buffer [10]: BYTE,                                      \
  63.                        x_increment: WORD, x_offset: WORD, x_size: WORD,        \
  64.                        y_increment: WORD, y_offset: WORD,                      \
  65.                        day_number: BYTE, day_max: BYTE,                        \
  66.                        x_counter: BYTE, y_counter: BYTE,                       \
  67.                        datetime [SIZ DATETIME]: BYTE, current_flag: BYTE
  68.  
  69. parm_offset   EQU      WPT parm_pointer
  70. parm_seg      EQU      WPT parm_pointer + 2
  71.  
  72. point_2       EQU      rectl.rcl_xRight
  73.  
  74.  
  75. ;  Establish addressability to data segment
  76.  
  77.               mov      ax, @data              ; get address
  78.               mov      ds, ax                 ;  of data segment
  79.  
  80. ;  Get address of saved parameter segment
  81.  
  82.               @WinQueryWindowPtr hwnd, 0, parm_pointer
  83.  
  84. ;  Examine message and route to applicable code
  85.  
  86.               @route   msg,                                                    \
  87.                        WM_CREATE, do_create,                                   \
  88.                        WM_SETWINDOWPARAMS, do_setwindowparams,                 \
  89.                        WM_PAINT, do_paint,                                     \
  90.                        WM_DESTROY, do_destroy
  91.  
  92. ;  No applicable code this message, do default processing
  93. default:
  94.               @WinDefWindowProc hwnd, msg, mp1, mp2
  95.  
  96. ;  Exit window procedure with current return code in dx:ax
  97. return:
  98.               ret                             ; return
  99.  
  100.  
  101. ;  WM_CREATE processing:
  102. ;     allocate segment for local copy of parameters,
  103. ;     set address of this segment of window pointer
  104. do_create:
  105.               @DosAllocSeg <SIZ PARAMETERS>, parm_seg, SEG_NONSHARED
  106.  
  107.               mov      parm_offset, 0         ; set area offset
  108.               les      di, parm_pointer       ; local copy area address
  109.               @WinSetWindowPtr hwnd, 0, es:di
  110.  
  111.               @return  0                      ; return
  112.  
  113.  
  114. ;  WM_SETWINDOWPARAMS processing:
  115. ;     get parameters passed to class and saved in allocated segment,
  116. ;     call for window repaint
  117. do_setwindowparams:
  118.               les      di, mp1                ; get address in window params
  119.               les      di, es: wprm_pszText [di]  ; parameter address
  120.               mov      ax, es: [di]           ; get input month
  121.               mov      dx, es: [di + 2]       ; get input year
  122.               les      di, parm_pointer       ; local copy area address
  123.               mov      es: parm_month [di], ax    ; set month
  124.               mov      es: parm_year [di], dx ; set year
  125.  
  126.               @WinInvalidateRegion hwnd, NULL, FALSE
  127.  
  128.               @return  1                      ; return
  129.  
  130.  
  131. ;  WM_PAINT processing:
  132. ;     paint the area for the 'CALENDAR' class
  133. do_paint:
  134.  
  135. ;  Clear direction flag
  136.  
  137.               cld                             ; clear direction flag
  138.  
  139. ;  Get the current day, month and year and check if selected month and year is
  140. ;   current. If so, set indicator flag.
  141.  
  142.               @DosGetDateTime datetime
  143.  
  144.               les      di, parm_pointer       ; parameter address
  145.               mov      current_flag, 0        ; indicate not current month/year
  146.               mov      ax, es: parm_month [di]    ; get specified month
  147.               cmp      al, datetime.date_month    ; current month?
  148.               jne      @f                     ; no, skip
  149.               mov      ax, es: parm_year [di] ; get specified year
  150.               cmp      ax, datetime.date_year ; current year?
  151.               jne      @f                     ; no, skip
  152.               mov      current_flag, 1        ; indicate current month/year
  153.  
  154. ;  Get number of days in specified month
  155.  
  156. @@:           mov      ax, es: parm_month [di]    ; get specified month
  157.               dec      ax                     ; absolute number
  158.               mov      bx, OFF normal_year    ; address normal table
  159.               test     BPT es: parm_year [di], 3  ; leap year?
  160.               jnz      @f                     ; no, skip
  161.               mov      bx, OFF leap_year      ; address leap year table
  162. @@:           xlat                            ; get days this month
  163.               mov      day_max, al            ;  and save result
  164.  
  165. ;  This logic computes the day in week for given month and year
  166.  
  167.               mov      ax, es: parm_year [di] ; specified year
  168.               dec      ax                     ; absolute
  169.               mov      dx, ax                 ; copy year
  170.               shr      ax, 2                  ; year / 4
  171.               imul     ax, 5                  ; (year / 4) * 5
  172.               and      dx, 3                  ; (year / 4) * 5 + 3
  173.               add      ax, dx                 ; (year / 4) * 5 + 3 + year
  174.  
  175.               mov      cx, es: parm_month [di]    ; get specified month
  176.               dec      cx                     ; absolute
  177.               jz       do_paint_1             ; first month, skip
  178.  
  179. @@:           add      al, [bx]               ; add days
  180.               adc      ah, 0                  ;  in month
  181.               inc      bx                     ; update table entry address
  182.               loop     @b                     ; next month
  183.  
  184. ;  Compute offset in calendar (ie. day in week for 1st of month)
  185. do_paint_1:
  186.               dec      ax                     ; adjust
  187.               cwd                             ;  and set for divide
  188.               mov      cx, 7                  ; days in week
  189.               div      cx                     ; divide
  190.               neg      dl                     ; offset in calendar
  191.               mov      day_number, dl         ; save it
  192.  
  193. ;  Get the dimensions of the window and fill with coloured box
  194.  
  195.               @WinQueryWindowRect hwnd, rectl
  196.  
  197.               @WinBeginPaint hwnd, NULL, NULL, hps
  198.  
  199.               @GpiMove hps, rectl
  200.               @GpiSetColor hps, CLR_PALEGRAY
  201.               @GpiBox  hps, DRO_FILL, point_2, 20, 20
  202.  
  203. ;  Divide into grid 6 rows by 7 columns,
  204. ;   save height/width as x/y increment and set offset to half remainder
  205.  
  206.               mov      ax, WPT rectl.rcl_xRight   ; window height
  207.               cwd                             ; set for divide
  208.               mov      cx, 7                  ; number of rows
  209.               div      cx                     ; row height
  210.               mov      x_increment, ax        ; save it as increment
  211.               shr      dx, 1                  ; halve remainder
  212.               mov      x_offset, dx           ; save it as offset
  213.               mov      ax, WPT rectl.rcl_yTop ; window width
  214.               cwd                             ; set for divide
  215.               mov      cx, 6                  ; number of columns
  216.               div      cx                     ; column width
  217.               mov      y_increment, ax        ; save it as increment
  218.               shr      dx, 1                  ; halve remainder
  219.               mov      y_offset, dx           ; save it as offset
  220.  
  221. ;  Compute placement of two digits within cell and save as cell width for write
  222.  
  223.               mov      ax, x_increment        ; get cell width
  224.               mov      WPT rectl.rcl_xRight, ax   ; set as rectl width
  225.               mov      ax, y_increment        ; get cell height
  226.               mov      WPT rectl.rcl_yTop, ax ; set as rectl height
  227.  
  228.               @WinDrawText hps, 2, two_digits, rectl, NULL, NULL,              \
  229.                        <DT_CENTER OR DT_QUERYEXTENT>
  230.  
  231.               mov      ax, WPT rectl.rcl_xRight   ; offset following right digit
  232.               mov      x_size, ax             ; save it as used cell size
  233.  
  234. ;  Get window address of first line
  235.  
  236.               imul     ax, y_increment, 5     ; length to top row
  237.               add      ax, y_offset           ; plus offset
  238.               mov      WPT rectl.rcl_yBottom, ax  ; save as lower coordinates
  239.               add      ax, y_increment        ; plus cell height
  240.               mov      WPT rectl.rcl_yTop, ax ; save as upper coordinates
  241.  
  242. ;  Line count
  243.  
  244.               mov      y_counter, 6           ; row count
  245.  
  246. ;  Get window address of first column
  247. do_paint_2:
  248.               mov      ax, x_offset           ; length to left column
  249.               mov      WPT rectl.rcl_xLeft, ax    ; save as left coordinates
  250.               add      ax, x_size             ; plus used cell width
  251.               mov      WPT rectl.rcl_xRight, ax   ; save as right coordinates
  252.  
  253. ;  Column count
  254.  
  255.               mov      x_counter, 7           ; column count
  256.  
  257. ;  Get day number and increment, check if in range
  258. do_paint_3:
  259.               mov      al, day_number         ; get day number
  260.               inc      al                     ; update
  261.               mov      day_number, al         ;  and save result
  262.               jle      do_paint_4             ; less than 1, skip
  263.               cmp      al, day_max            ; exceeds days this month?
  264.               ja       do_paint_5             ; yes, all done
  265.  
  266. ;  Set text colour depending on whether day/month/year is current
  267.  
  268.               mov      cx, CLR_NEUTRAL        ; set neutral colour
  269.               cmp      current_flag, 1        ; is month/year current?
  270.               jne      @f                     ; no, use neutral
  271.               cmp      al, datetime.date_day  ; is day number today's?
  272.               jne      @f                     ; no, use neutral
  273.               mov      cx, CLR_WHITE          ; current day/month/year, white
  274.  
  275. ;  Set buffer address and convert day number
  276.  
  277. @@:           push     ss                     ; copy address
  278.               pop      es                     ;  of stack segment
  279.               lea      di, buffer             ; address of buffer
  280.               call     convert_num_1          ; convert day number
  281.               mov      BPT es: [di], 0        ; set null terminator
  282.  
  283. ;  Set day number in cell in window
  284.  
  285.               @WinDrawText hps, -1, buffer, rectl, cx, CLR_BACKGROUND,         \
  286.                        <DT_RIGHT OR DT_VCENTER>
  287.  
  288. ;  Update x coordindate and loop if more to do
  289. do_paint_4:
  290.               mov      ax, x_increment        ; get x increment
  291.               add      WPT rectl.rcl_xLeft, ax    ;  and update
  292.               add      WPT rectl.rcl_xRight, ax   ;  cell x coordinate
  293.  
  294.               dec      x_counter              ; update column counter
  295.               jnz      do_paint_3             ; more columns, loop
  296.  
  297. ;  Update y coordindate and loop if more to do
  298.  
  299.               mov      ax, y_increment        ; get y increment
  300.               sub      WPT rectl.rcl_yBottom, ax  ;  and update
  301.               sub      WPT rectl.rcl_yTop, ax ;  cell y coordinate
  302.  
  303.               dec      y_counter              ; update row number
  304.               jnz      do_paint_2             ; more rows, loop
  305.  
  306. ;  Paint complete, free hps
  307. do_paint_5:
  308.               @WinEndPaint hps
  309.  
  310.               @return  0                      ; return
  311.  
  312.  
  313. ;  WM_DESTROY processing:
  314. ;     free local parameter segment
  315. do_destroy:
  316.               @DosFreeSeg parm_seg
  317.  
  318.               @return  0                      ; return
  319.  
  320.  
  321. calendar_proc ENDP
  322.               PAGE
  323.               END
  324. 
  325.  
  326.  
  327.