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

.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: 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
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 
就是说,我创建一个窗口,大小是整个屏幕。然后把屏幕的dc 颜色取反拷给自己,然后在鼠标左击消息中,创建一个子窗口,并根据鼠标左击按下并移动消息,设置子窗口的大小。现在大小能设置,有两个坐标点存在。一个是窗口创建时那个坐标,一个是鼠标移动时的坐标。但是鼠标移动的坐标有时我计算的不对。唔,这个我想到办法了,那个,由于子窗口是WS_POPUPWINDOW风格,那么我在运行时如何拖动它改变窗口的大小?
2012-07-30 11:49
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 

代码不是越长越好的。
难道我需要定义4中cursor,自己判断鼠标是否在子窗口边界?
2012-07-30 13:35
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 
求思路。
2012-07-30 16:53
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 
语言只是工具,不用太纠结。
选取目标区域
这步总得给用户修改大小和移动的机会吧?
2012-07-30 18:00
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 
不只是画框呀,鼠标在边界还得改变鼠标形状呢。
2012-07-31 00:23
邋遢鬼
Rank: 2
等 级:论坛游民
帖 子:29
专家分:94
注 册:2011-5-29
收藏
得分:0 
全屏窗口的大小是不变的。那么要不就不创建子窗口了,在全屏窗口的目标区域画一个边框,并设置4种鼠标形状。在WM_MOUSEMOVE消息中判断当前光标形状来进行某种操作。我回去再试下。
本来创建子窗口的目的只是为了方便控制。如果只有一个全屏窗口的话,所有坐标都是相对于自己的坐标原点,或许操作更加方便。
2012-07-31 18:03
快速回复:编写截屏工具遇到的问题
数据加载中...
 
   



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

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