| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1446 人关注过本帖
标题:编写截屏工具遇到的问题
只看楼主 加入收藏
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
结帖率:0
收藏
已结贴  问题点数:20 回复次数:24 
编写截屏工具遇到的问题

.386
.Model Flat, StdCall
Option Casemap :None

Include D:\masm32\include\windows.inc
Include D:\masm32\include\user32.inc
Include D:\masm32\include\kernel32.inc
Include D:\masm32\include\gdi32.inc

includelib D:\masm32\lib\gdi32.lib
IncludeLib D:\masm32\lib\user32.lib
IncludeLib D:\masm32\lib\kernel32.lib
   
.DATA
    szClassName db "MASMPlus_Class",0
    szChildClassName db "Class",0
    hInstance    dd ?;实例句柄
    lpError        dd ?;如果使用GetLastError函数话,使用这个变量做字符串指针
    stRect        RECT <>
    hDCScreen    dd ?;内存DC句柄
    hBmpScreen    dd ?;内存位图句柄
    hChildWnd    dd ?;子窗口句柄
    point        dd ?,?;鼠标指针位置
    oldpoint    dd ?,?;同上
.CODE

_ChildProc proc uses ebx esi edi hWnd,uMsg,wParam,lParam
    local @hDC
    local @stPs:PAINTSTRUCT
    mov eax,uMsg
    .if eax == WM_PAINT
        invoke BeginPaint,hWnd,addr @stPs
        mov @hDC,eax
        invoke GetClientRect,hWnd,offset stRect
        mov eax,oldpoint
        mov ecx,oldpoint+4;取得子窗口原点相对父窗口原点的位移
        invoke BitBlt,@hDC,0,0,stRect.right,stRect.bottom,\
            hDCScreen,eax,ecx,NOTSRCCOPY
        invoke EndPaint,hWnd,addr @stPs
    .elseif eax == WM_SIZE
        mov esi,lParam
        test esi,esi
        jz @ret
        mov eax,point
        mov ecx,point+4
        mov edi,esi
        and esi,0fffh
        shr edi,16
        cmp eax,esi;小的放eax做子窗口的原点
        jb @f
        je @ret
            xchg eax,esi
        @@:
        sub esi,eax;得到x轴增量
        cmp ecx,edi
        jb @f
        je @ret
            xchg ecx,edi
        @@:
        sub edi,ecx;得到y轴增量
        mov oldpoint,eax
        mov oldpoint+4,ecx;临时原点坐标
        invoke SetWindowPos,hWnd,HWND_TOPMOST,eax,ecx,esi,edi,SWP_SHOWWINDOW;设置窗口大小和位置
        invoke InvalidateRect,hWnd,0,FALSE;刷新屏幕
    .elseif eax == WM_CLOSE||eax == WM_KEYDOWN
        invoke DestroyWindow,hWnd
    .else
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .endif
    @ret:
    xor eax,eax
    ret
_ChildProc endp
WndProc proc uses ebx esi edi hWnd:DWORD,uMsg:DWORD,wParam :DWORD,lParam :DWORD
    local @stPs:PAINTSTRUCT
    local @hDC
    mov eax,uMsg
    .if eax == WM_PAINT;拷贝临时内存DC到自己的DC
        invoke BeginPaint,hWnd,addr @stPs
        mov @hDC,eax
        invoke GetClientRect,hWnd,offset stRect
        invoke BitBlt,@hDC,0,0,stRect.right,stRect.bottom,hDCScreen,0,0,SRCCOPY
        invoke EndPaint,hWnd,addr @stPs
    .elseif eax == WM_CREATE
        invoke GetDesktopWindow;得到桌面的窗口句柄
        push eax
        invoke GetClientRect,eax,offset stRect;获取它的客户区大小
        mov eax,[esp]
        invoke GetDC,eax;获取桌面DC
        mov @hDC,eax
        invoke CreateCompatibleDC,eax;创建内存DC
        mov hDCScreen,eax
        invoke CreateCompatibleBitmap,@hDC,stRect.right,stRect.bottom;创建内存位图
        mov hBmpScreen,eax
        invoke SelectObject,hDCScreen,hBmpScreen;装入位图

        invoke BitBlt,hDCScreen,0,0,stRect.right,stRect.bottom,@hDC,0,0,NOTSRCCOPY
        pop eax;从桌面DC拷贝到临时内存DC
        invoke ReleaseDC,eax,@hDC

    .elseif eax == WM_MOUSEMOVE
        .if wParam == MK_LBUTTON
            invoke SendMessage,hChildWnd,WM_SIZE,SIZE_RESTORED,lParam
        .endif;在WM_MOUSEMOVE消息中改变子窗口大小
    .elseif eax == WM_LBUTTONDOWN
        .if hChildWnd != 0;如果已经创建,就先关闭它
            invoke SendMessage,hChildWnd,WM_CLOSE,0,0
        .endif
        mov eax,lParam
        mov ecx,eax
        shr ecx,16
        and eax,0ffffh
        mov point,eax
        mov point+4,ecx
        mov oldpoint,eax
        mov oldpoint+4,ecx;计算子窗口的显示位置
        invoke CreateWindowEx,WS_EX_TOPMOST,offset szChildClassName,0,\
            WS_POPUP or WS_CHILD or WS_THICKFRAME,\
            eax,ecx,2,2,hWnd,NULL,hInstance,NULL
            
        mov hChildWnd,eax
        invoke ShowWindow,eax,SW_SHOWNORMAL;显示窗口
        invoke UpdateWindow,hChildWnd
    .elseif eax == WM_RBUTTONDOWN
        invoke SendMessage,hChildWnd,WM_CLOSE,0,0;右键关闭子窗口
    .elseif eax == WM_DESTROY||eax==WM_KEYDOWN
        invoke SendMessage,hChildWnd,WM_CLOSE,0,0
        invoke PostQuitMessage,NULL
        invoke DeleteDC,hDCScreen
        invoke DeleteObject,hBmpScreen
    .else
        invoke DefWindowProc,hWnd,eax,wParam,lParam
        ret
    .endif
    xor eax,eax
    ret
WndProc endp
WinMain proc
    LOCAL @WC   :WNDCLASSEX
    LOCAL @Msg  :MSG
    local @hWnd :HWND
    invoke RtlZeroMemory,addr @WC,sizeof @WC
    mov @WC.cbSize,sizeof WNDCLASSEX
    mov @WC.style,CS_HREDRAW or CS_VREDRAW
    mov @WC.lpfnWndProc,offset WndProc
    push hInstance
    pop @WC.hInstance
    mov @WC.lpszClassName,offset szClassName
    invoke LoadCursor,0,IDC_ARROW
    mov @WC.hCursor,eax
    invoke RegisterClassEx, ADDR @WC
    ;父窗口的窗口类
    mov @WC.lpszClassName,offset szChildClassName
    mov @WC.lpfnWndProc,offset _ChildProc
    invoke RegisterClassEx, ADDR @WC
    ;子窗口的窗口类
    invoke CreateWindowEx,0,ADDR szClassName,0,WS_POPUPWINDOW,\
        500,300,400,400,NULL,NULL,hInstance,NULL
        ;创建一个全屏无边框窗口
    mov @hWnd,eax
    invoke ShowWindow,@hWnd,SW_MAXIMIZE;最大化
    invoke UpdateWindow,@hWnd
    StartLoop:
        invoke GetMessage,ADDR @Msg,NULL,0,0
            or eax,eax
            je ExitLoop
                invoke DispatchMessage, ADDR @Msg
            jmp StartLoop
    ExitLoop:
   
mov eax,@Msg.wParam
ret
WinMain endp


START:

    invoke GetModuleHandle,NULL
    mov hInstance,eax
    invoke WinMain
    invoke ExitProcess,0

END START

错误表现为 我从某个点向右下截屏,却截到的点坐上的,令请指点WS_POPUPWINDOW风格的窗口如何在运行时设置大小。
搜索更多相关主题的帖子: 工具 include 字符串 
2012-07-29 13:48
信箱有效
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:蒙面侠
威 望:9
帖 子:1102
专家分:4268
注 册:2012-6-19
收藏
得分:5 
看不懂
2012-07-29 15:28
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:5 
太长了 祝楼主早日解决问题。。
2012-07-29 15:29
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 

不要这样嘛。我真心求帮助。为何系统发送的WM_SIZE消息的lParam会为0呢?还有,我判断以小的坐标做子窗口左上角的坐标,但是有时会反。不懂了,真心求指点的。
2012-07-29 19:03
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 
2012-07-29 23:27
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
看了看 没明白咋回事
2012-07-29 23:45
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 
就是说,我创建一个窗口,大小是整个屏幕。然后把屏幕的dc 颜色取反拷给自己,然后在鼠标左击消息中,创建一个子窗口,并根据鼠标左击按下并移动消息,设置子窗口的大小。现在大小能设置,有两个坐标点存在。一个是窗口创建时那个坐标,一个是鼠标移动时的坐标。但是鼠标移动的坐标有时我计算的不对。唔,这个我想到办法了,那个,由于子窗口是WS_POPUPWINDOW风格,那么我在运行时如何拖动它改变窗口的大小?
2012-07-30 11:49
信箱有效
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:蒙面侠
威 望:9
帖 子:1102
专家分:4268
注 册:2012-6-19
收藏
得分:0 
楼主好厉害 能写出这么长的代码。 我要拜你为师。
2012-07-30 12:42
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 

代码不是越长越好的。
难道我需要定义4中cursor,自己判断鼠标是否在子窗口边界?
2012-07-30 13:35
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
同拜师

感觉你这个实现方法不大好 虽然我也不知道怎么写好。。
2012-07-30 13:36
快速回复:编写截屏工具遇到的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.049632 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved