欢迎访问:常州市武进区嘉泽中心小学网站 !今天是:
栏目列表
您现在的位置是:首页>>教师>>计算机技术>>程序设计>>杂项>>文章内容
利用 cards.dll 写自己的扑克程序
发布时间:2008-11-20   点击:   来源:本站原创   录入者:佚名
  利用 cards.dll 写自己的扑克程序

  观察 Windows 自带的纸牌、空当接龙等扑克游戏会发现他们都利用到了 cards.dll 这个动态链接库,从中引入了 cdtInit 和 cdtDrawExt 等函数来实现扑克的绘制等工作。其实我们也可以利用 cards.dll 来写一个我们自己的扑克游戏。下面的示意图就是一个小的测试程序,用到了 cdtDrawExt 等函数绘制了所有扑克,扑克背面的图案,反色绘制扑克等等。这里是例子代码,这里是引入 cards.dll 所需要的 cards.lib

  例子代码的示意图,点击查看大图

  为了在程序中调用 cards.dll,我们首先要搞清楚的就是 cards.dll 导出的每一个函数的用法,包括参数、返回值等等。关于这一点你可以自己反汇编纸牌游戏和 cards.dll 来分析反汇编后的代码从而得出每一个函数的用法,也可以参考 MSJ Spring 1996 中的文章 Fun and Games。当然,我在后面也会介绍每一个函数的用法。

  知道了函数的用法后,我们考虑要在程序中用 invoke 的方法来调用函数,就需要构建一个引入库 cards.lib。由于引入库中不需要包含具体的代码,所以我们自己写一个动态库,导出和 cards.dll 一样的导出函数,那么编译连接动态库时生成的引入库就可以拿来使用。

.386

.model flat,stdcall

option casemap:none



.code



cdtInit proc p1:DWORD, p2:DWORD

cdtInit endp



cdtDraw proc p1:DWORD, p2:DWORD, p3:DWORD, p4:DWORD, p5:DWORD, p6:DWORD

cdtDraw endp



cdtDrawExt proc p1:DWORD, p2:DWORD, p3:DWORD, p4:DWORD, p5:DWORD, p6:DWORD, p7:DWORD, p8:DWORD

cdtDrawExt endp



cdtAnimate proc p1:DWORD, p2:DWORD, p3:DWORD, p4:DWORD, p5:DWORD

cdtAnimate endp



cdtTerm proc

cdtTerm endp



end

好,有了引入库后我们就可以很方便的利用 invoke 来调用函数啦。下面介绍几个主要函数的用法:

cdtInit proc lpdwCardWidth:DWORD, lpdwCardHeight:DWORD



lpdwCardWidth   返回扑克的宽度

lpdwCardHeight  返回扑克的高度

cdtDraw proc hDC:DWORD, dwX:DWORD, dwY:DWORD, cd:DWORD, md:DWORD, rgbBkgnd:DWORD

cdtDrawExt proc hDC:DWORD, dwX:DWORD, dwY:DWORD, dwdx:DWORD, dwdy:DWORD, cd:DWORD, md:DWORD, rgbBkgnd:DWORD



hDC     设备句柄

dwX     左上角的位置的横坐标

dwY     左上角的位置的纵坐标

cd      指出绘制哪一张扑克,或哪一个背景,具体对应的序号可以参考例子代码中的 Cards.inc 文件

md      绘制方式,有以下几种

        mdFace             EQU         0      ;绘制各种花色扑克

        mdBackground       EQU         1      ;绘制各种背景

        mdHilite           EQU         2      ;反色绘制各种花色扑克,不支持反色背景

        mdGhost            EQU         3      ;绘制网格图

        mdRemove           EQU         4      ;采用背景颜色绘制一个扑克大小的矩形

        mdInvisibleGhost   EQU         5      ;绘制网格图

        mdDeckX            EQU         6      ;绘制 X 图

        mdDeckO            EQU         7      ;绘制 O 图

rgbBk   绘制背景时的背景颜色



dwdx    绘制放大的或缩小的扑克时的宽度

dwdy    绘制放大的或缩小的扑克时的高度

cdtTerm 没有参数

有关上面几个函数的具体用法我们来看看例子代码:

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

        local   hDC:HDC

        local   ps:PAINTSTRUCT



        .IF uMsg==WM_DESTROY

                invoke  cdtTerm

                invoke  PostQuitMessage, NULL



        .ELSEIF uMsg==WM_CREATE

                invoke  cdtInit, addr nCardWidth, addr nCardHeight

                invoke  ShowWindow, hWnd, SW_MAXIMIZE



        .ELSEIF uMsg==WM_PAINT

                invoke  BeginPaint, hWnd, addr ps

                mov     hDC, eax



        ;===========================\   按每种花色的顺序绘制 4 列扑克

                xor     ecx, ecx

                xor     ebx, ebx

                mov     esi, 10

            @1:

                mov     edi, 12h

                mov     ebx, ecx

            @2:

                push    ecx

                invoke  cdtDraw, hDC, esi, edi, ebx, mdFace, rgbBground

                pop     ecx

                add     edi, 12h

                add     ebx, 4

                cmp     ebx, 52

                jb      @2

                add     esi, nCardWidth

                add     esi, 10

                inc     ecx

                cmp     ecx, 4

                jz      @3

                jmp     @1

            @3:

        ;===========================/



        ;===========================\   绘制所有的可用背景

                mov     ebx, 54

                mov     esi, 10

                mov     edi, 400

            @@:

                invoke  cdtDraw, hDC, esi, edi, ebx, mdBackground, rgbBground

                inc     ebx

                add     esi, nCardWidth

                add     esi, 10

                cmp     ebx, 66

                jnz     @B

        ;===========================/



        ;===========================\   反色绘制各种花色的扑克

                mov     ebx, 0

                mov     esi, 10

                mov     edi, 500

            @@:

                invoke  cdtDraw, hDC, esi, edi, ebx, mdHilite, rgbBground

                add     ebx, 5

                add     esi, nCardWidth

                add     esi, 10

                cmp     ebx, 55

                jnz     @B

        ;===========================/



        ;===========================\   其它几种绘制方式

                mov     ebx, 6

                mov     esi, 10

                mov     edi, 600

                invoke  cdtDraw, hDC, esi, edi, ebx, mdGhost, rgbBground

                add     ebx, 5

                add     esi, nCardWidth

                add     esi, 10

                RGB     255, 0, 0

                invoke  cdtDraw, hDC, esi, edi, ebx, mdRemove, eax

                add     ebx, 5

                add     esi, nCardWidth

                add     esi, 10

                invoke  cdtDraw, hDC, esi, edi, ebx, mdInvisibleGhost, rgbBground

                add     esi, nCardWidth

                add     esi, 10

                invoke  cdtDraw, hDC, esi, edi, ebx, mdDeckX, rgbBground

                add     esi, nCardWidth

                add     esi, 10

                invoke  cdtDraw, hDC, esi, edi, ebx, mdDeckO, rgbBground

        ;===========================/



                invoke  EndPaint, hWnd, addr ps



        .ELSE

                invoke  DefWindowProc, hWnd, uMsg, wParam, lParam

                ret

        .ENDIF

        xor eax,eax

        ret

WndProc endp

怎么样,再看看前面的示意图,3.5KB 就有这样的效果,是不是很酷!在代码区还有一个用 C+SDK 方式编写的空当接龙源代码,大家如果有兴趣可以看看。


CopyRight (C) 2001-2004 一块三毛钱

附件:
    关闭窗口
    打印文档
    账号登录
    保持登录 忘记密码?
    账号与武进教师培训平台同步