回 帖 发 新 帖 刷新版面

主题:[讨论]难道微软的屏幕和客户区间坐标转换函数有错误??

各位朋友好!!
我是初学SDK,看到有的窗口可以改变大小,但是小到一定的高和宽程序就不允许再改,比如说QQ的窗口。
于是我用以下代码也试着做一个,不知道正确实现方法是不是这种,
但还不是我最疑惑的问题,而是关于屏幕和客户区间坐标转换函数计算误差,
代码如下,并不长:
假定创建窗口时给定的位置:x=260,y=200,宽度=550,高度=380,
要求程序只能使它变大而不能在小于此值:

case WM_SIZING:
    if( ((PRECT)lParam)->right - ((PRECT)lParam)->left < 550 ||
    ((PRECT)lParam)->bottom - ((PRECT)lParam)->top < 380 )
    {
    pt.x = 0;
    pt.y = 0;
    ClientToScreen(hwnd,&pt);
    rect.left = pt.x;
    rect.top = pt.y;

    pt.x = 550;
    pt.y = 380;
    ClientToScreen(hwnd,&pt);
    rect.right = pt.x;
    rect.bottom = pt.y;

    hdc = GetDC(hwnd);
    wsprintf(Buf,"L%i,T%i",rect.left,rect.top);
    TextOut(hdc,0,0,Buf,lstrlen(Buf));
    wsprintf(Buf,"R%i,B%i",rect.right,rect.bottom);
    TextOut(hdc,0,16,Buf,lstrlen(Buf));
    ReleaseDC(hwnd,hdc);
            
    ((PRECT)lParam)->left = rect.left-4; //转换后的值水平有误差4个像素
    ((PRECT)lParam)->top = rect.top-31; //转换后的值垂直有误差31个像素
    ((PRECT)lParam)->right = rect.right-4;
         ((PRECT)lParam)->bottom = rect.bottom-31;
}
return TRUE;

如果第一次显示窗口,默认的位置将是创建时给定的260和200,此时在边框上单击而
不拖动鼠标将会显示当前窗口的4个值。
此时屏幕坐标应该为 左260 上200  右810  下580
而显示在窗口左上角TextOut的经过转换成屏幕坐标的窗口区域4个值时,水平方向即
左和右正确值多4个像素:264, 814,垂直方向即顶部和底部多31个像素:231,611,
没办法才将水平的值后边-4,垂直的后边-32,此后程序运行正常,效果理想了。

请问这个错误是我这新手学艺不精,又什么地方疏忽了造成的还是此版本的函数就存在着问题?  请各位高手朋友帮忙分析一下,不胜感激!!
还有,我的这种方法是不是想实现此功能的标准惯用的方法?如果不是请好心人给出正确的代码,谢谢你们了!!  


回复列表 (共7个回复)

沙发

补充:我使用的是VC++6.0,操作系统是Windows XPsp2  感觉与此版本操作系统有些不兼容的效果  是这样吗?  后来我又写了别的窗口的程序,也把这个消息加了进去,但是没想到这个值的偏差居然还发生变化了,水平还是偏差4像素,垂直的竟然偏差51个像素了……  这到底怎么回事啊??

板凳

各位高手们啊  这个问题就真的没人回答吗??  对于你们并不是难题吧  帮忙分析一下啊  小弟在此谢过了  我绝对不是部给分的小人啊

3 楼

真的不想看,这么复杂,楼主你把不明白的地方说出来好了,何必代码跟描述这么多

4 楼

楼上的朋友,详细点没坏处吧? 我是复制的代码  觉得没做什么工作……  太长了  不好意思  如题ScreenToClient转换函数转换出的值有误差  第一次试验和第二次试验的偏差值还不同  你知道原因吗?  我觉得函数不该有错误  可能我的代码什么地方逻辑出错才贴上的……这回够短的了吧?呵

5 楼

客户区的(0,0)其实不是窗口的起始点(260,200),主要是算上边框的size,如果你从客户区的(0,0)为起点绘制一条线,你会发现它不是从窗口的起始点开始绘制,而是从窗口边框的右边一点以及标题栏(可能还有菜单栏)下方开始,所以水平偏差有4个象素,而竖直没有菜单是偏差31,若有菜单是51吧。。。。。。。

6 楼

原来是这样计算的啊  这细节都能被你发现  太强了  我还真打算找机会测试的  但是一直没时间  就忽略这些细节了  楼上的大哥谢谢你了!!
还有我这种写法到底对不对啊?是不是标准的?

7 楼

限制窗口大小,可以用WM_GETMINMAXINFO消息
注意有屏幕Screen,窗口Window,客户区Client之分

我来回复

您尚未登录,请登录后再回复。点此登录或注册