ctypes通過使用 Windows API庫,在 Python 中獲取當前滑鼠指標位置很簡單。但是,似乎從滑鼠指標的螢屏位置 position (x,y)開始,獲取當前終端視窗的當前文本游標位置,似乎是一個巨大的困難。
此外,程式員社區不斷將滑鼠指標位置與文本游標位置混淆,這使情況變得更糟。歷史上從來沒有滑鼠“游標”,所以當人們說“游標”時,他們應該指的是文本游標,而不是相反。由于這個錯誤,Stackoverflow 充滿了與“游標”有關的問題和答案,但似乎與獲取終端外殼的當前字符位置無關。[被詛咒的游標!]
獲取相對滑鼠指標位置:
from ctypes import windll, wintypes, byref
def get_cursor_pos():
cursor = wintypes.POINT()
windll.user32.GetCursorPos(byref(cursor))
return (cursor.x, cursor.y)
while(1): print('{}\t\t\r'.format(get_cursor_pos()), end='')
我想要一個函式,它可以在字符 row 和column方面給我最后一個位置。也許是這樣的:
def cpos():
xy = here_be_magic()
return xy
# Clear screen and start from top:
print('\x1b[H', end='');
print('12345', end='', flush=True); xy=cpos(); print('( {},{})'.format(xy[0],xy[1]),end='', flush=True)
# 12345 (1,5) # written on top of blank screen
如何在終端內的(行,列text)中獲取游標位置?
(并且不做任何假設并且不必撰寫我自己的視窗管理器?)
最終我希望用它來找到任何終端視窗中的最后一個游標位置,(并且可能被任何程式使用?)
可能相關(但無用)的 SO 問題:
- 獲取當前鍵游標位置文本[C#]
- 如何在 Windows 中獲取文本游標位置?[老鼠?]
- 如何在 python readline [滑鼠?]中獲取當前游標位置
- 如何在PowerShell控制臺中更改游標位置
- python ctypes,通過參考傳遞雙指標
- Python 和 ctypes:如何正確地將“指標對指標”傳遞給 DLL?
更新(2022-01-17)
通過查看 MS 檔案,我現在確信應該可以從(較舊的、非基于 VT 的)API 呼叫中獲取它,GetConsoleScreenBufferInfo它是這樣給出的。
BOOL WINAPI GetConsoleScreenBufferInfo(
_In_ HANDLE hConsoleOutput, # A handle to the console screen buffer. The handle must have the GENERIC_READ access right.
_Out_ PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo # A pointer to a CONSOLE_SCREEN_BUFFER_INFO structure that receives the console screen buffer information.
);
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
COORD dwSize; # contains the size of the console screen buffer, in character columns and rows.
COORD dwCursorPosition; # contains the column and row coordinates of the cursor in the console screen buffer.
WORD wAttributes; # Character attributes (divided into two classes: color and DBCS)
SMALL_RECT srWindow; # A SMALL_RECT structure that contains the console screen buffer coordinates of the upper-left and lower-right corners of the display window.
COORD dwMaximumWindowSize; # A COORD structure that contains the maximum size of the console window, in character columns and rows, given the current screen buffer size and font and the screen size.
} CONSOLE_SCREEN_BUFFER_INFO; #
# Defines the coordinates of a character cell in a console screen buffer.
# The origin of the coordinate system (0,0) is at the top, left cell of the buffer.
typedef struct _COORD {
SHORT X; # The horizontal coordinate or column value. The units depend on the function call.
SHORT Y; # The vertical coordinate or row value. The units depend on the function call.
} COORD, *PCOORD;
typedef struct _SMALL_RECT {
SHORT Left;
SHORT Top;
SHORT Right;
SHORT Bottom;
} SMALL_RECT;
因此,鑒于此,我認為以下方法會起作用。
cls='\x1b[H'
from ctypes import windll, wintypes, byref
def cpos():
cursor = wintypes._COORD(ctypes.c_short)
windll.kernel32.GetConsoleScreenBufferInfo(byref(cursor))
return (cursor.X, cursor.Y)
cpos()
# TypeError: '_ctypes.PyCSimpleType' object cannot be interpreted as an integer
uj5u.com熱心網友回復:
問題是找到各種結構定義。經過大量實驗后,我得到了以下作業解決方案。
#!/usr/bin/env python -u
# -*- coding: UTF-8 -*-
#------------------------------------------------------------------------------
from ctypes import windll, wintypes, Structure, c_short, c_ushort, byref, c_ulong
from readline import console
#------------------------------------------------
# Win32 API
#------------------------------------------------
SHORT = c_short
WORD = c_ushort
DWORD = c_ulong
STD_OUTPUT_HANDLE = DWORD(-11) # $CONOUT
# These are already defined, so no need to redefine.
COORD = wintypes._COORD
SMALL_RECT = wintypes.SMALL_RECT
CONSOLE_SCREEN_BUFFER_INFO = console.CONSOLE_SCREEN_BUFFER_INFO
#------------------------------------------------
# Main
#------------------------------------------------
wk32 = windll.kernel32
hSo = wk32.GetStdHandle(STD_OUTPUT_HANDLE)
GetCSBI = wk32.GetConsoleScreenBufferInfo
def cpos():
csbi = CONSOLE_SCREEN_BUFFER_INFO()
GetCSBI(hSo, byref(csbi))
xy = csbi.dwCursorPosition
return '({},{})'.format(xy.X,xy.Y)
cls='\x1b[H'
print('\n'*61)
print(cls '12345', end='', flush=True); print(' {}'.format(cpos()), flush=True)
# 12345 (5,503)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/415711.html
標籤:
上一篇:檢查屬性的空值
下一篇:使用C 捕獲特定視窗會回傳舊資料
