新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 利用 cards.dll写自己的扑克程序 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 8827 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 利用 cards.dll写自己的扑克程序 举报  打印  推荐  IE收藏夹 
       本主题类别: DOM    
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 利用 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 方式编写的空当接龙源代码,大家如果有兴趣可以看看。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2010/6/1 9:13:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/22 14:52:55

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms