guohq 发表于 2016-1-27 23:58:39

查了几天资料,终于找到求解方法,具体如下

1.通过 doc.Window.Handle 获取 当前文档窗口的句柄 68478(以下列出的数值皆为说明问题,每个人计算出的结果都不会一样)

2.获取 doc.Window对象下的所有子窗口,用到两个 api函数

    <DllImport("user32.DLL", EntryPoint:="GetTopWindow", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
    Public Shared Function GetTopWindow(ByVal hWnd As IntPtr) As IntPtr

    End Function


    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Public Shared Function GetWindow(ByVal hWnd As IntPtr, ByVal uCmd As UInt32) As IntPtr

    End Function

   调用如下:
   
   GetTopWindow(68478)=330634顶层窗口
   GetWindow(330634,2) =   68484   第二个窗口(2代表 同级别Z序之下,具体解百度下)
   GetWindow(68484,2)=   134058第三个窗口
   GetWindow(134058,2) =0   此处说明没有窗口了
从上面的情况来看,每个CAD文档窗口下,都会有3个子窗口

3.根据窗口句柄获取窗口的大小与位置,使用下面api函数即可

<DllImport("user32.dll")> _
    Private Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
    End Function

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure RECT
      Public Left As Integer '       // x position of upper-left corner
      Public Top As Integer ';         // y position of upper-left corner
      Public Right As Integer ';       // x position of lower-right corner
      Public Bottom As Integer ';      // y position of lower-right corner
    End Structure

    dim Rec as new RECT
    GetWindowRect(68478 ,Rec)获取文档窗口的大小 与位置 (经查证,Rec返回的值 与 doc.Window.Location 与doc.Window.Size的值完全一致)

    GetWindowRect(330634 ,Rec)获取第一个子窗口的大小与位置(此值获取后,发现Left与Right值一样,Bottom与Top值一个,说明此窗口是一个大小为0的窗口,肯定不是绘图区域)

   GetWindowRect(68484 ,Rec)获取第二个子窗口的大小与位置(此值获取后,用Right减Left Bottom减Top的值 与 doc.GraphicsManager.DisplaySize的值大小一值,说明此子窗口为绘图区域,而 Left与Top组成的值即为绘图区域左上角的坐标了 )

   GetWindowRect(134058 ,Rec) 获取三个子窗口的大小与位置(此值获取后,发现此窗口是一个高度为6个像素的窗口,不知道有什么用处)


以上即为 获取 绘图区域左上角坐标的详细分析过程。

cairunbin 发表于 2016-1-28 10:21:27

赞一下,赞分享。

llsheng_73 发表于 2016-1-28 18:09:59

(defun ScreenWin(/ h c);;当前屏幕对角坐标(wcs)
(setq c(trans(getvar'viewctr)1 0)
      h(*(getvar'viewsize)0.5)
        h(list(*(apply'/(getvar'screensize))h)h))
(mapcar'(lambda(x)(mapcar x c h))'(- +)))

guohq 发表于 2016-1-28 21:48:20

llsheng_73 发表于 2016-1-28 18:09 static/image/common/back.gif


我要计算的是屏幕的像素坐标

wz0406 发表于 2018-7-30 20:37:55

解决我一个难题,CAD截图

xgr 发表于 2019-5-30 13:54:45

本帖最后由 xgr 于 2019-5-30 14:00 编辑

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;

namespace 取得CAD绘图区域屏幕坐标
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

[DllImport("user32.DLL", EntryPoint = "GetTopWindow", SetLastError = true, CharSet = CharSet.Unicode,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]

public static extern IntPtr GetTopWindow(IntPtr hWnd);


public static extern IntPtr GetWindow(IntPtr hWnd, UInt32 uCmd);



static extern bool GetWindowRect(IntPtr hWnd, ref Rect lpRect);


public struct Rect
{
public int Left; //最左坐标
public int Top; //最上坐标
public int Right; //最右坐标
public int Bottom; //最下坐标
}

private void button1_Click(object sender, EventArgs e)
{
Rect rect = new Rect();
IntPtr intPtr1 = GetTopWindow(Application.DocumentManager.MdiActiveDocument.Window.Handle);
textBox1.Text = intPtr1.ToString();
IntPtr intPtr2 = GetWindow(intPtr1, 2);
GetWindowRect(intPtr2, ref rect);
textBox2.Text = rect.Left.ToString();
textBox3.Text = rect.Top.ToString();
textBox4.Text = (rect.Right - rect.Left).ToString();
textBox5.Text = (rect.Bottom - rect.Top).ToString();
}
}
}

枫叶棋语 发表于 2023-12-23 21:00:11

from pycad.system import *
from pycad.runtime import *
import ctypes
import clr

clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
clr.AddReference("PresentationCore")
clr.AddReference("PresentationFramework")
clr.AddReference("WindowsBase")
clr.AddReference("OpenCvSharp")
clr.AddReference("OpenCvSharp.Extensions")
import OpenCvSharp as cv
from OpenCvSharp import Cv2
from OpenCvSharp.Extensions import BitmapConverter
from System.Windows.Forms import Form, Control, NativeWindow
from System.Drawing import Point, Bitmap, Graphics
from System.Windows.Forms import Screen


class POINT(ctypes.Structure):
    _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]


def get_mouse_position():
    pt = POINT()
    ctypes.windll.user32.GetCursorPos(ctypes.byref(pt))
    return pt.x, pt.y



x_offset = 0
y_offset = 0


@Command()
def InitialScreen(doc: Document):
    """屏幕坐标校准"""
    global x_offset, y_offset
    ed = doc.Editor
    res = getpoint()
    if not res.ok:
      return
    cad_pt = res.value# tpye:Point3d
    windowpt = get_mouse_position()# 屏幕的绝对坐标
    view_pt = ed.PointToScreen(cad_pt, 0)# CAD视口的相对坐标
    # 求出坐标偏移值
    x_offset = windowpt - view_pt.X
    y_offset = windowpt - view_pt.Y


def capture_screen(pt1: Point, pt2: Point):
    """截屏"""
    x1, x2, y1, y2 = int(pt1.X), int(pt2.X), int(pt1.Y), int(pt2.Y)
    xmin = min(x1, x2) - 1
    xmax = max(x1, x2) + 1
    ymin = min(y1, y2) - 1
    ymax = max(y1, y2) + 1

    width = xmax - xmin
    height = ymax - ymin
    bitmap = Bitmap(width, height)
    graphics = Graphics.FromImage(bitmap)
    graphics.CopyFromScreen(xmin, ymin, 0, 0, bitmap.Size)
    return bitmap


@Command()
def CaptureScreen(doc: Document):
    global x_offset, y_offset
    ed = doc.Editor
    res = getpoint()
    if not res.ok:
      return
    pt1 = res.value
    res = getcorner(basept=pt1)
    if not res.ok:
      return
    pt2 = res.value

    winpts = []
    for pt in :
      screenpt = ed.PointToScreen(pt, 0)
      windowpt = Point(int(screenpt.X + x_offset), int(screenpt.Y + y_offset))
      winpts.append(windowpt)

    screenshot = capture_screen(winpts, winpts)
    mat = BitmapConverter.ToMat(screenshot)
    prinf(mat)
    Cv2.ImShow("img", mat)

d1742647821 发表于 2023-12-26 09:11:20

本帖最后由 d1742647821 于 2023-12-26 09:19 编辑

可以参考一下

CAD坐标转为屏幕坐标
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=189169&fromuid=7329732
(出处: 明经CAD社区)




页: 1 [2]
查看完整版本: 怎样获取CAD绘图区域左上角的屏幕坐标