关于 SENDKEYS 的代码
sendkeys 的用法(MSDN):
SendKeys 語句
??? ???
將一個或多個按鍵消息發送到活動窗口,就如同在鍵盤上進行輸入一樣。
語法
SendKeys string[, wait]
SendKeys 語句的語法具有以下幾個命名參數:
| string | 必需的。字符串表達式,指定要發送的按鍵消息。 |
| Wait | 可選的。指定等待方式的 BooleandefBooleanDataType@veendf98.chm 值。如果為 False(缺省值),則控件在按鍵發送出去之后立刻返回到過程。如果為 True,則按鍵消息必須在控件返回到過程之前加以處理。 |
?
說明
每個按鍵由一個或多個字符表示。為了指定單一鍵盤字符,必須按字符本身的鍵。例如,為了表示字母 A,可以用 "A" 作為 string。為了表示多個字符,就必須在字符后面直接加上另一個字符。例如,要表示 A、B 及 C,可用 "ABC" 作為 string。
對 SendKeys 來說,加號 (+)、插入符 (^)、百分比符號 (%)、上劃線 (~) 及圓括號 ( ) 都具有特殊意義。為了指定上述任何一個字符,要將它放在大括號 ({}) 當中。例如,要指定正號,可用 {+} 表示。方括號 ([ ]) 對 SendKeys 來說并不具有特殊意義,但必須將它們放在大括號中。在其它應用程序中,方括號有特殊意義,在出現動態數據交換 (DDE) 的時候,它可能具有重要意義。為了指定大括號字符,請使用 {{} 及 {}}。
為了在按下按鍵時指定那些不顯示的字符,例如 ENTER 或 TAB 以及那些表示動作而非字符的按鍵,請使用下列代碼:
| BACKSPACE | {BACKSPACE}, {BS}, 或 {BKSP} |
| BREAK | {BREAK} |
| CAPS LOCK | {CAPSLOCK} |
| DEL or DELETE | {DELETE} 或 {DEL} |
| DOWN ARROW | {DOWN} |
| END | {END} |
| ENTER | {ENTER}或 ~ |
| ESC | {ESC} |
| HELP | {HELP} |
| HOME | {HOME} |
| INS or INSERT | {INSERT} 或 {INS} |
| LEFT ARROW | {LEFT} |
| NUM LOCK | {NUMLOCK} |
| PAGE DOWN | {PGDN} |
| PAGE UP | {PGUP} |
| PRINT SCREEN | {PRTSC} |
| RIGHT ARROW | {RIGHT} |
| SCROLL LOCK | {SCROLLLOCK} |
| TAB | {TAB} |
| UP ARROW | {UP} |
| F1 | {F1} |
| F2 | {F2} |
| F3 | {F3} |
| F4 | {F4} |
| F5 | {F5} |
| F6 | {F6} |
| F7 | {F7} |
| F8 | {F8} |
| F9 | {F9} |
| F10 | {F10} |
| F11 | {F11} |
| F12 | {F12} |
| F13 | {F13} |
| F14 | {F14} |
| F15 | {F15} |
| F16 | {F16} |
?
為了指定那些與 SHIFT、CTRL 及 ALT 等按鍵結合的組合鍵,可在這些按鍵碼的前面放置一個或多個代碼,這些代碼列舉如下:
| SHIFT | + |
| CTRL | ^ |
| ALT | % |
?
為了說明在按下其它按鍵時應同時按下 SHIFT、CTRL、及 ALT 的任意組合鍵,請把那些按鍵的碼放在括號當中。例如,為了說明按下 E 與 C 的時候同時按下 SHIFT 鍵,請使用 "+(EC)"。為了說明在按下 E 的時候同時按下 SHIFT 鍵,但接著按 C 而不按 SHIFT,則使用 "+EC"。
為了指定重復鍵,使用 {key number} 的形式。必須在 key 與 number 之間放置一個空格。例如,{LEFT 42} 意指 42 次按下 LEFT ARROW 鍵;{h 10} 則是指 10 次按下 H 鍵。
注意 不能用 SendKeys 將按鍵消息發送到這樣一個應用程序,這個應用程序并沒有被設計成在 Microsoft Windows or Macintosh中運行。Sendkeys 也無法將 PRINT SCREEN 按鍵 {PRTSC} 發送到任何應用程序。
我們如果想發送鍵命令,可以用 SENDKEYS ,但要發送 WINDOWS 微標鍵怎么做?(MSDN中沒有給出WINDOWS鍵 的鍵碼)
下面是可以執行的代碼:
Private?Const?VK_LWIN?=?&H5B?'Left?Windows?key?(Microsoft?Natural?keyboard)
Private?Const?VK_RWIN?=?&H5C?'Right?Windows?key?(Natural?keyboard)
Private?Sub?Command1_Click()?'left?windows
keybd_event?VK_LWIN,?0,?&H1,?0
keybd_event?VK_LWIN,?0,?&H2,?0
End?Sub
Private?Sub?Command2_Click()?'right?windows
keybd_event?VK_RWIN,?0,?&H1,?0
keybd_event?VK_RWIN,?0,?&H2,?0
End?Sub
?
詳細的解釋可參看SENDKEYS 類(http://www.vbaccelerator.com/home/VB/Tips/SendKeys_using_the_API/SendKeys_Demonstration_zip_cSendKeys_cls.asp):
vbAccelerator?-?Contents?of?code?file:?cSendKeys.clsVERSION?1.0?CLASSBEGIN
??MultiUse?=?-1??'True
END
Attribute?VB_Name?=?"cSendKeys"
Attribute?VB_GlobalNameSpace?=?False
Attribute?VB_Creatable?=?True
Attribute?VB_PredeclaredId?=?False
Attribute?VB_Exposed?=?False
Option?Explicit
Public?Enum?MoreKeyConstants
???VK_LWIN?=?&H5B?'Left?Windows?key?(Microsoft?Natural?keyboard)
???VK_RWIN?=?&H5C?'Right?Windows?key?(Natural?keyboard)
???VK_APPS?=?&H5D?'Applications?key?(Natural?keyboard)
???VK_SLEEP?=?&H5F?'Computer?Sleep?key
???
???VK_RMENU?=?&HA5?'?Right?MENU?key
???VK_BROWSER_BACK?=?&HA6?'Windows?2000/XP:?Browser?Back?key
???VK_BROWSER_FORWARD?=?&HA7?'Windows?2000/XP:?Browser?Forward?key
???VK_BROWSER_REFRESH?=?&HA8?'Windows?2000/XP:?Browser?Refresh?key
???VK_BROWSER_STOP?=?&HA9?'Windows?2000/XP:?Browser?Stop?key
???VK_BROWSER_SEARCH?=?&HAA?'Windows?2000/XP:?Browser?Search?key
???VK_BROWSER_FAVORITES?=?&HAB?'Windows?2000/XP:?Browser?Favorites?key
???VK_BROWSER_HOME?=?&HAC?'Windows?2000/XP:?Browser?Start?and?Home?key
???VK_VOLUME_MUTE?=?&HAD?'Windows?2000/XP:?Volume?Mute?key
???VK_VOLUME_DOWN?=?&HAE??'Windows?2000/XP:?Volume?Down?key
???VK_VOLUME_UP?=?&HAF??'Windows?2000/XP:?Volume?Up?key
???VK_MEDIA_NEXT_TRACK?=?&HB0??'Windows?2000/XP:?Next?Track?key
???VK_MEDIA_PREV_TRACK?=?&HB1??'Windows?2000/XP:?Previous?Track?key
???VK_MEDIA_STOP?=?&HB2??'Windows?2000/XP:?Stop?Media?key
???VK_MEDIA_PLAY_PAUSE?=?&HB3??'Windows?2000/XP:?Play/Pause?Media?key
???VK_LAUNCH_MAIL?=?&HB4??'Windows?2000/XP:?Start?Mail?key
???VK_LAUNCH_MEDIA_SELECT?=?&HB5??'Windows?2000/XP:?Select?Media?key
???VK_LAUNCH_APP1?=?&HB6??'Windows?2000/XP:?Start?Application?1?key
???VK_LAUNCH_APP2?=?&HB7??'Windows?2000/XP:?Start?Application?2?key
???VK_OEM_1?=?&HBA?'Used?for?miscellaneous?characters;?it?can?vary?by?keyboard.
????Windows?2000/XP:?For?the?US?standard?keyboard,?the?';:'?key
?
???VK_OEM_PLUS?=?&HBB?'Windows?2000/XP:?For?any?country/region,?the?'+'?key
???VK_OEM_COMMA?=?&HBC?'Windows?2000/XP:?For?any?country/region,?the?','?key
???VK_OEM_MINUS?=?&HBD?'Windows?2000/XP:?For?any?country/region,?the?'-'?key
???VK_OEM_PERIOD?=?&HBE?'Windows?2000/XP:?For?any?country/region,?the?'.'?key
???VK_OEM_2?=?&HBF?'Used?for?miscellaneous?characters;?it?can?vary?by?keyboard.
????Windows?2000/XP:?For?the?US?standard?keyboard,?the?'/?'?key
???VK_OEM_3?=?&HC0?'Used?for?miscellaneous?characters;?it?can?vary?by?keyboard.
????Windows?2000/XP:?For?the?US?standard?keyboard,?the?'`~'?key
'??C1D7?Reserved
'??D8DA?Unassigned
???VK_OEM_4?=?&HDB?'Used?for?miscellaneous?characters;?it?can?vary?by?keyboard.
????Windows?2000/XP:?For?the?US?standard?keyboard,?the?'[{'?key
???VK_OEM_5?=?&HDC?'Used?for?miscellaneous?characters;?it?can?vary?by?keyboard.
????Windows?2000/XP:?For?the?US?standard?keyboard,?the?'|'?key
???VK_OEM_6?=?&HDD?'Used?for?miscellaneous?characters;?it?can?vary?by?keyboard
????Windows?2000/XP:?For?the?US?standard?keyboard,?the?']}'?key
???VK_OEM_7?=?&HDE?'?Used?for?miscellaneous?characters;?it?can?vary?by
????keyboard.?Windows?2000/XP:?For?the?US?standard?keyboard,?the
????'single-quote/double-quote'?key
???VK_OEM_8?=?&HDF?'Used?for?miscellaneous?characters;?it?can?vary?by?keyboard.
??????E0?Reserved
'-?E1?OEM?specific
???VK_OEM_102?=?&HE2?'Windows?2000/XP:?Either?the?angle?bracket?key?or?the
????backslash?key?on?the?RT?102-key?keyboard
'?E3E4?OEM?specific
???VK_PROCESSKEY?=?&HE5?'Windows?95/98/Me,?Windows?NT?4.0,?Windows?2000/XP:?IME
????PROCESS?key
'?E6?OEM?specific
???VK_PACKET?=?&HE7?'Windows?2000/XP:?Used?to?pass?Unicode?characters?as?if
????they?were?keystrokes.?The?VK_PACKET?key?is?the?low?word?of?a?32-bit?Virtual
????Key?value?used?for?non-keyboard?input?methods.?For?more?information,?see
????Remark?in?KEYBDINPUT,?SendInput,?WM_KEYDOWN,?and?WM_KEYUP
'??E8?Unassigned
'?E9F5?OEM?specific
???VK_ATTN?=?&HF6?'Attn?key
???VK_CRSEL?=?&HF7?'CrSel?key
???VK_EXSEL?=?&HF8?'ExSel?key
???VK_EREOF?=?&HF9?'Erase?EOF?key
???VK_PLAY?=?&HFA?'Play?key
???VK_ZOOM?=?&HFB?'Zoom?key
???VK_NONAME?=?&HFC?'Reserved?for?future?use
???VK_PA1?=?&HFD?'PA1?key
???VK_OEM_CLEAR?=?&HFE?'Clear?key
End?Enum
Private?m_colKeyMap?As?New?Collection
Private?Declare?Sub?keybd_event?Lib?"user32"?(?_
???ByVal?bVk?As?Byte,?ByVal?bScan?As?Byte,?_
???ByVal?dwFlags?As?Long,?ByVal?dwExtraInfo?As?Long)
Private?Const?KEYEVENTF_EXTENDEDKEY?=?&H1
Private?Const?KEYEVENTF_KEYUP?=?&H2
Private?Declare?Function?GetVersion?Lib?"kernel32"?()?As?Long
Private?Declare?Function?VkKeyScan?Lib?"user32"?Alias?"VkKeyScanA"?(?_
???ByVal?cChar?As?Byte)?As?Integer
Private?Declare?Function?VkKeyScanW?Lib?"user32"?(?_
???ByVal?cChar?As?Integer)?As?Integer
Private?Declare?Sub?CopyMemory?Lib?"kernel32"?Alias?"RtlMoveMemory"?(?_
????lpvDest?As?Any,?lpvSource?As?Any,?ByVal?cbCopy?As?Long)
Private?Function?nextChar(ByRef?sString?As?String,?ByVal?iPos?As?Long,?Optional
?ByVal?lLen?As?Long?=?0)?As?String
???If?(lLen?=?0)?Then?lLen?=?Len(sString)
???If?(iPos?+?1?<=?lLen)?Then
??????nextChar?=?Mid$(sString,?iPos?+?1,?1)
???End?If
End?Function
Public?Sub?SendKeys(ByVal?sKeys?As?String,?Optional?ByVal?Wait?As?Boolean)
???'?The?plus?sign?(+),?caret?(^),?percent?sign?(%),
???'?tilde?(~),?and?parentheses?(?)?have?special
???'?meanings?to?SendKeys
???'?Brackets?([?])?have?no?special?meaning?to?SendKeys,
???'?but?you?must?enclose?them?in?braces.
???'?To?specify?brace?characters,?use?{{}?and?{}}.
???'?Repeating?keys:?{LEFT?42}?do?left?42?times.
???
???'?+?=?Shift
???'?^?=?Ctrl
???'?%?=?Alt
???'?~?=?enter
???'?(?=?start?sub?expression.?+(EC)?=?Shift?then?E?then?C
??????
On?Error?GoTo?errorHandler
???Dim?sMsg?As?String
???Dim?lErr?As?Long
???Dim?iPos?As?Long
???Dim?iNextPos?As?Long
???Dim?iLen?As?Long
???Dim?sChar?As?String
???Dim?colBrace?As?New?Collection
???Dim?sContent?As?String
???Dim?sKey?As?String
???Dim?sCount?As?String
???Dim?lCount?As?Long
???iPos?=?1
???iLen?=?Len(sKeys)
???Do?While?iPos?<=?iLen
???
??????sChar?=?Mid$(sKeys,?iPos,?1)
??????Select?Case?sChar
??????Case?"+",?"~",?"%"
?????????If?nextChar(sKeys,?iPos,?iLen)?=?"("?Then
????????????'?Add?to?brace?stack:
????????????colBrace.Add?sChar
????????????'?send?key?down
????????????Select?Case?sChar
????????????Case?"+"
???????????????KeyDown?vbKeyShift
????????????Case?"~"
???????????????KeyDown?vbKeyControl
????????????Case?"%"
???????????????KeyDown?vbKeyMenu
????????????End?Select
????????????iPos?=?iPos?+?2
?????????Else
????????????'?Key?press?the?key?(probably?not?what?you?wanted)
????????????Select?Case?sChar
????????????Case?"+"
???????????????KeyDown?vbKeyShift
???????????????KeyUp?vbKeyShift
????????????Case?"~"
???????????????KeyDown?vbKeyControl
???????????????KeyUp?vbKeyControl
????????????Case?"%"
???????????????KeyDown?vbKeyMenu
???????????????KeyUp?vbKeyMenu
????????????End?Select
????????????iPos?=?iPos?+?1
?????????End?If
??????
??????Case?"~"
?????????'?Enter?key:
?????????KeyDown?vbKeyReturn
?????????KeyUp?vbKeyReturn
?????????iPos?=?iPos?+?1
?????????
??????Case?")"
?????????If?(colBrace.Count?>?0)?Then
????????????sChar?=?colBrace(colBrace.Count)
????????????'?send?key?up
????????????Select?Case?sChar
????????????Case?"+"
???????????????KeyUp?vbKeyShift
????????????Case?"~"
???????????????KeyUp?vbKeyControl
????????????Case?"%"
???????????????KeyUp?vbKeyMenu
????????????End?Select
????????????colBrace.Remove?colBrace.Count
????????????iPos?=?iPos?+?1
?????????Else
????????????'?Invalid?sendkeys?command:
????????????sMsg?=?"Invalid?sendkeys?command:?unmatched?)?at?position?"?&?iPos
????????????GoTo?errorHandler
?????????End?If
??????
??????Case?"{"
?????????'?special?key
?????????If?(iPos?+?2?>?iLen)?Then
????????????sMsg?=?"Invalid?sendkeys?command;?opening?{?without?content?or
?????????????closing?}?at?position?"?&?iPos
????????????GoTo?errorHandler
?????????Else
????????????iNextPos?=?InStr(iPos?+?2,?sKeys,?"}")
????????????If?(iNextPos?=?0)?Then
???????????????sMsg?=?"Invalid?sendkeys?command;?opening?{?without?closing?}?at
????????????????position?"?&?iPos
???????????????GoTo?errorHandler
????????????Else
???????????????sContent?=?Mid$(sKeys,?iPos?+?1,?iNextPos?-?iPos?-?1)
???????????????iPos?=?iNextPos?+?1
???????????????'?is?this?a?key/presses?pair?
???????????????iNextPos?=?InStr(sContent,?"?")
???????????????If?(iNextPos?>?0)?Then
??????????????????sKey?=?Left$(sContent,?iNextPos?-?1)
??????????????????sCount?=?Mid$(sContent,?iNextPos?+?1)
??????????????????If?Not?(IsNumeric(sCount))?Then
?????????????????????sMsg?=?"Invalid?sendkeys?command;?key?repetitions?'"?&
??????????????????????sCount?&?"'?is?invalid?near?position?"?&?iPos
?????????????????????lCount?=?CLng(sCount)
??????????????????End?If
???????????????Else
??????????????????sKey?=?sContent
??????????????????lCount?=?1
???????????????End?If
???????????????KeyPress?sKey,?lCount
???????????????
????????????End?If
?????????End?If
?????????
??????Case?Else
?????????'?send?the?key?as?is
?????????KeyPress?sChar,?1
?????????iPos?=?iPos?+?1
?????????
??????End?Select
???
???Loop
???
???If?(colBrace.Count?>?0)?Then
??????sMsg?=?"Invalid?sendkeys?command:?more?open?brackets?than?close?brackets."
??????GoTo?errorHandler
???End?If
???
???Exit?Sub
???
errorHandler:
???If?Len(sMsg)?=?0?Then
??????sMsg?=?Err.Description
??????lErr?=?Err.Number
???End?If
???
???'?If?we?don't?clear?up?the?shift/control/alt?keys,
???'?then?you?might?find?other?apps?on?the?system?are?hard?to
???'?use.
???'?Make?sure?you?have?Break?on?Unhandled?Errors?switched
???'?on.
???Do?While?colBrace.Count?>?0
??????sChar?=?colBrace(colBrace.Count)
??????'?send?key?up
??????Select?Case?sChar
??????Case?"+"
?????????KeyUp?vbKeyShift
??????Case?"~"
?????????KeyUp?vbKeyControl
??????Case?"%"
?????????KeyUp?vbKeyMenu
??????End?Select
??????colBrace.Remove?colBrace.Count
???Loop
???
???On?Error?GoTo?0
???Err.Raise?lErr,?App.EXEName?&?".cSendKeys",?sMsg
???
???Exit?Sub
End?Sub
Public?Sub?KeyPress(ByVal?sKey?As?String,?Optional?ByVal?lCount?=?1)
Dim?vKey?As?KeyCodeConstants
Dim?l?As?Long
???On?Error?Resume?Next
???vKey?=?m_colKeyMap(sKey)
???On?Error?GoTo?0
???
???If?(vKey?=?0)?Then
??????'?translate?string?into?v?key?code
??????vKey?=?KeyCode(sKey)
???End?If
???
???If?(vKey?<>?0)?Then
??????For?l?=?1?To?lCount
?????????KeyDown?vKey
?????????KeyUp?vKey
??????Next?l
???Else
??????Err.Raise?9,?,?"Key?"?&?sKey?&?"?could?not?be?interpreted."
???End?If
???
End?Sub
Public?Sub?KeyDown(ByVal?vKey?As?KeyCodeConstants)
???keybd_event?vKey,?0,?KEYEVENTF_EXTENDEDKEY,?0
End?Sub
Public?Sub?KeyUp(ByVal?vKey?As?KeyCodeConstants)
???keybd_event?vKey,?0,?KEYEVENTF_EXTENDEDKEY?Or?KEYEVENTF_KEYUP,?0
End?Sub
Public?Function?KeyCode(ByVal?sChar?As?String)?As?KeyCodeConstants
Dim?bNt?As?Boolean
Dim?iKeyCode?As?Integer
Dim?b()?As?Byte
Dim?iKey?As?Integer
Dim?vKey?As?KeyCodeConstants
Dim?iShift?As?ShiftConstants
???'?Determine?if?we?have?Unicode?support?or?not:
???bNt?=?((GetVersion()?And?&H80000000)?=?0)
???
???'?Get?the?keyboard?scan?code?for?the?character:
???If?(bNt)?Then
??????b?=?sChar
??????CopyMemory?iKey,?b(0),?2
??????iKeyCode?=?VkKeyScanW(iKey)
???Else
??????b?=?StrConv(sChar,?vbFromUnicode)
??????iKeyCode?=?VkKeyScan(b(0))
???End?If
???
???KeyCode?=?(iKeyCode?And?&HFF&)
End?Function
Private?Sub?Class_Initialize()
???m_colKeyMap.Add?vbKeyBack,?"BACKSPACE"
???m_colKeyMap.Add?vbKeyBack,?"BS"
???m_colKeyMap.Add?vbKeyBack,?"BKSP"
???m_colKeyMap.Add?vbKeyPause,?"BREAK"
???m_colKeyMap.Add?vbKeyCapital,?"CAPSLOCK"
???m_colKeyMap.Add?vbKeyDelete,?"DELETE"
???m_colKeyMap.Add?vbKeyDelete,?"DEL"
???m_colKeyMap.Add?vbKeyDown,?"DOWN"
???m_colKeyMap.Add?vbKeyEnd,?"END"
???m_colKeyMap.Add?vbKeyReturn,?"ENTER"
???m_colKeyMap.Add?vbKeyReturn,?"~"
???m_colKeyMap.Add?vbKeyEscape,?"ESC"
???m_colKeyMap.Add?vbKeyHelp,?"HELP"
???m_colKeyMap.Add?vbKeyHome,?"HOME"
???m_colKeyMap.Add?vbKeyInsert,?"INS"
???m_colKeyMap.Add?vbKeyInsert,?"INSERT"
???m_colKeyMap.Add?vbKeyLeft,?"LEFT"
???m_colKeyMap.Add?vbKeyNumlock,?"NUMLOCK"
???m_colKeyMap.Add?vbKeyPageDown,?"PGDN"
???m_colKeyMap.Add?vbKeyPageUp,?"PGUP"
???m_colKeyMap.Add?vbKeyPrint,?"PRTSC"
???m_colKeyMap.Add?vbKeyRight,?"RIGHT"
???m_colKeyMap.Add?vbKeyScrollLock,?"SCROLLLOCK"
???m_colKeyMap.Add?vbKeyTab,?"TAB"
???m_colKeyMap.Add?vbKeyUp,?"UP"
???m_colKeyMap.Add?vbKeyF1,?"F1"
???m_colKeyMap.Add?vbKeyF2,?"F2"
???m_colKeyMap.Add?vbKeyF3,?"F3"
???m_colKeyMap.Add?vbKeyF4,?"F4"
???m_colKeyMap.Add?vbKeyF5,?"F5"
???m_colKeyMap.Add?vbKeyF6,?"F6"
???m_colKeyMap.Add?vbKeyF7,?"F7"
???m_colKeyMap.Add?vbKeyF8,?"F8"
???m_colKeyMap.Add?vbKeyF9,?"F9"
???m_colKeyMap.Add?vbKeyF10,?"F10"
???m_colKeyMap.Add?vbKeyF11,?"F11"
???m_colKeyMap.Add?vbKeyF12,?"F12"
???m_colKeyMap.Add?vbKeyF13,?"F13"
???m_colKeyMap.Add?vbKeyF14,?"F14"
???m_colKeyMap.Add?vbKeyF15,?"F15"
???m_colKeyMap.Add?vbKeyF16,?"F16"
End?Sub
轉載于:https://www.cnblogs.com/fengju/archive/2005/09/26/6336364.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的关于 SENDKEYS 的代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用.NET类库操作CSV文件
- 下一篇: 输卵管通液术和输卵管造影区别主要是什么?