明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: guohq

[图形系统] 怎样获取CAD绘图区域左上角的屏幕坐标

  [复制链接]
 楼主| 发表于 2016-1-27 23:58 | 显示全部楼层
查了几天资料,终于找到求解方法,具体如下

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个像素的窗口,不知道有什么用处)


以上即为 获取 绘图区域左上角坐标的详细分析过程。
发表于 2016-1-28 10:21 | 显示全部楼层
赞一下,赞分享。
发表于 2016-1-28 18:09 | 显示全部楼层
  1. (defun ScreenWin(/ h c);;当前屏幕对角坐标(wcs)
  2.   (setq c(trans(getvar'viewctr)1 0)
  3.         h(*(getvar'viewsize)0.5)
  4.         h(list(*(apply'/(getvar'screensize))h)h))
  5.   (mapcar'(lambda(x)(mapcar x c h))'(- +)))
 楼主| 发表于 2016-1-28 21:48 | 显示全部楼层
llsheng_73 发表于 2016-1-28 18:09

我要计算的是屏幕的像素坐标
发表于 2018-7-30 20:37 | 显示全部楼层
解决我一个难题,CAD截图
发表于 2019-5-30 13:54 | 显示全部楼层
本帖最后由 xgr 于 2019-5-30 14:00 编辑
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Windows.Forms;
  4. using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;

  5. namespace 取得CAD绘图区域屏幕坐标
  6. {
  7. public partial class Form1 : Form
  8. {
  9. public Form1()
  10. {
  11. InitializeComponent();
  12. }

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

  15. public static extern IntPtr GetTopWindow(IntPtr hWnd);

  16. [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  17. public static extern IntPtr GetWindow(IntPtr hWnd, UInt32 uCmd);

  18. [DllImport("user32.dll")]
  19. [return: MarshalAs(UnmanagedType.Bool)]
  20. static extern bool GetWindowRect(IntPtr hWnd, ref Rect lpRect);

  21. [StructLayout(LayoutKind.Sequential)]
  22. public struct Rect
  23. {
  24. public int Left; //最左坐标
  25. public int Top; //最上坐标
  26. public int Right; //最右坐标
  27. public int Bottom; //最下坐标
  28. }

  29. private void button1_Click(object sender, EventArgs e)
  30. {
  31. Rect rect = new Rect();
  32. IntPtr intPtr1 = GetTopWindow(Application.DocumentManager.MdiActiveDocument.Window.Handle);
  33. textBox1.Text = intPtr1.ToString();
  34. IntPtr intPtr2 = GetWindow(intPtr1, 2);
  35. GetWindowRect(intPtr2, ref rect);
  36. textBox2.Text = rect.Left.ToString();
  37. textBox3.Text = rect.Top.ToString();
  38. textBox4.Text = (rect.Right - rect.Left).ToString();
  39. textBox5.Text = (rect.Bottom - rect.Top).ToString();
  40. }
  41. }
  42. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2023-12-23 21:00 | 显示全部楼层
  1. from pycad.system import *
  2. from pycad.runtime import *
  3. import ctypes
  4. import clr

  5. clr.AddReference("System.Drawing")
  6. clr.AddReference("System.Windows.Forms")
  7. clr.AddReference("PresentationCore")
  8. clr.AddReference("PresentationFramework")
  9. clr.AddReference("WindowsBase")
  10. clr.AddReference("OpenCvSharp")
  11. clr.AddReference("OpenCvSharp.Extensions")
  12. import OpenCvSharp as cv
  13. from OpenCvSharp import Cv2
  14. from OpenCvSharp.Extensions import BitmapConverter
  15. from System.Windows.Forms import Form, Control, NativeWindow
  16. from System.Drawing import Point, Bitmap, Graphics
  17. from System.Windows.Forms import Screen


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


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



  24. x_offset = 0
  25. y_offset = 0


  26. @Command()
  27. def InitialScreen(doc: Document):
  28.     """屏幕坐标校准"""
  29.     global x_offset, y_offset
  30.     ed = doc.Editor
  31.     res = getpoint()
  32.     if not res.ok:
  33.         return
  34.     cad_pt = res.value  # tpye:Point3d
  35.     windowpt = get_mouse_position()  # 屏幕的绝对坐标
  36.     view_pt = ed.PointToScreen(cad_pt, 0)  # CAD视口的相对坐标
  37.     # 求出坐标偏移值
  38.     x_offset = windowpt[0] - view_pt.X
  39.     y_offset = windowpt[1] - view_pt.Y


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

  47.     width = xmax - xmin
  48.     height = ymax - ymin
  49.     bitmap = Bitmap(width, height)
  50.     graphics = Graphics.FromImage(bitmap)
  51.     graphics.CopyFromScreen(xmin, ymin, 0, 0, bitmap.Size)
  52.     return bitmap


  53. @Command()
  54. def CaptureScreen(doc: Document):
  55.     global x_offset, y_offset
  56.     ed = doc.Editor
  57.     res = getpoint()
  58.     if not res.ok:
  59.         return
  60.     pt1 = res.value
  61.     res = getcorner(basept=pt1)
  62.     if not res.ok:
  63.         return
  64.     pt2 = res.value

  65.     winpts = []
  66.     for pt in [pt1, pt2]:
  67.         screenpt = ed.PointToScreen(pt, 0)
  68.         windowpt = Point(int(screenpt.X + x_offset), int(screenpt.Y + y_offset))
  69.         winpts.append(windowpt)

  70.     screenshot = capture_screen(winpts[0], winpts[1])
  71.     mat = BitmapConverter.ToMat(screenshot)
  72.     prinf(mat)
  73.     Cv2.ImShow("img", mat)
复制代码
发表于 2023-12-26 09:11 | 显示全部楼层
本帖最后由 d1742647821 于 2023-12-26 09:19 编辑

可以参考一下

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




您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-3-28 23:39 , Processed in 0.172797 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表