> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GameInput 回呼

> GameInput 回呼

<a id="introductionSection" />

雖然 `GameInput` 主要是圍繞輪詢模型設計的，但在某些情況下，以非同步方式通知應用程式是最佳做法。為了支援此需求，[IGameInput](/zh-TW/reference/input/gameinput/interfaces/igameinput/igameinput) 介面公開了幾個方法，用於註冊在發生特定相關事件時叫用的回呼函式。

在內部，`GameInput` 會將回呼的分派序列化，讓一次只執行一個回呼。`GameInput` 保證回呼會依時間順序分派。這些保證可簡化應用程式需要在其回呼函式中撰寫的程式碼。

`GameInput` 在任何時間最多允許註冊 64 個回呼，不論類型為何。回呼是從 `GameInput` 中的內部背景工作執行緒分派。如需此運作方式的詳細資訊，以及手動排程此工作的選項，請參閱 [GameInput 工作佇列](/zh-TW/build/core-features/common/input/advanced/input-work-queues)。

<a id="deviceCallbacksSection" />

## 裝置回呼

裝置回呼可讓應用程式得知輸入裝置的狀態何時變更，如下列語法所示。最常見的用途是偵測裝置何時連線和中斷連線，但其他狀態變更也可能值得關注。

```c++ theme={null}
HRESULT RegisterDeviceCallback(
    _In_opt_ IGameInputDevice * device,
    _In_ GameInputKind inputKind,
    _In_ GameInputDeviceStatus statusFilter,
    _In_ GameInputEnumerationKind enumerationKind,
    _In_opt_ void * context,
    _In_ GameInputDeviceCallback callbackFunc,
    _Out_opt_ _Result_zeroonfailure_ GameInputCallbackToken * callbackToken);
```

裝置回呼可以搭配數個選用篩選條件註冊。這包括篩選出產生特定輸入類型的裝置、篩選特定狀態變更、篩選特定裝置，或這些篩選條件的任意組合。例如，應用程式可以設定回呼，在裝置與系統中斷連線時通知應用程式。

除了裝置狀態變更之外，[RegisterDeviceCallback](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_registerdevicecallback) 方法也可用於裝置列舉。`enumerationKind` 參數接受 [GameInputEnumerationKind](/zh-TW/reference/input/gameinput/enums/gameinputenumerationkind) 列舉中的值，指出是否應在回呼註冊過程中執行列舉，如果是，則指出應以封鎖或非同步方式執行列舉。將裝置列舉與後續狀態變更結合成單一不可部分完成的作業，可避免許多應用程式在其輸入程式碼中無意間遭遇的競爭情形。

<a id="readingCallbacksSection" />

## 讀數回呼

透過讀數回呼，每當有新的讀數抵達輸入串流時，應用程式就會收到通知，如下列語法所示。雖然許多應用程式會發現輪詢輸入比較好，但在某些情況下，事件驅動的輸入可能更合適。例如，遊戲的主功能表 UI 可能更適合以事件為基礎的輸入。另一個範例是輸入對應 UI，它必須在提示使用者進行選擇之後等待輸入。

```c++ theme={null}
HRESULT RegisterReadingCallback(
    _In_opt_ IGameInputDevice * device,
    _In_ GameInputKind inputKind,
    _In_ float analogThreshold,
    _In_opt_ void * context,
    _In_ GameInputReadingCallback callbackFunc,
    _Out_opt_ _Result_zeroonfailure_ GameInputCallbackToken * callbackToken);
```

與裝置回呼一樣，讀數回呼也可以搭配數個選用篩選條件註冊。這對讀數回呼特別有用，因為應用程式可能只對輸入串流中特定的讀數子集感興趣。[RegisterReadingCallback](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_registerreadingcallback) 方法可篩選出產生特定輸入類型的裝置，和/或篩選特定裝置的輸入。

應用程式也可以為類比輸入值 (例如遊戲台的類比搖桿) 指定篩選條件，要求在回呼觸發之前達到某個最小移動量。當不需要高解析度的類比狀態變更時，這可以大幅降低回呼頻率。一個很好的例子是實作輸入對應 UI 時，在提示使用者進行選擇之後等待輸入變更。

<a id="unregisteringSection" />

## 取消註冊回呼

成功註冊回呼之後，應用程式必須保證執行回呼所需的任何資源都保持有效。這包括回呼程式碼所使用的資源，以及回呼函式本身，例如，回呼函式裝載在應用程式視需要載入和卸載的 DLL 中時。

若要安全地回收這些資源，應用程式必須先將從 `Register*Callback` 方法收到的權杖傳遞至 [UnregisterCallback](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_unregistercallback) 方法，以取消註冊回呼。如果呼叫此方法時回呼正在執行，此方法會封鎖直到回呼執行完成。因此，回呼無法從其自身的回呼函式內取消註冊自己。

也可以呼叫 [StopCallback](/zh-TW/reference/input/gameinput/interfaces/igameinput/methods/igameinput_stopcallback) 方法來停止回呼。這不會取消註冊回呼，但會確保不會再次呼叫該回呼。由於回呼未取消註冊，因此可以安全地從回呼自身的回呼函式內呼叫此方法。它會完成執行目前的回呼，但不會再次呼叫它。由於任何時間最多只允許 64 個回呼，因此最終仍必須取消註冊回呼。

<a id="seeAlsoSection" />

## 參考 API 文件

* [GameInput (API 內容)](/zh-TW/reference/input/gameinput/gameinput_members)

## 另請參閱

[GameInput 基本概念](/zh-TW/build/core-features/common/input/overviews/input-fundamentals)

[進階 GameInput 主題](/zh-TW/build/core-features/common/input/advanced/input-advanced-topics)

[輸入 API 參考](/zh-TW/reference/input/gc-reference-input-toc)


## Related topics

- [GameInput](/reference/input/gameinput/gameinput_members.md)
- [Overview of GameInput](/build/core-features/common/input/overviews/input-overview.md)
- [GameInput fundamentals](/build/core-features/common/input/overviews/input-fundamentals.md)
- [GameInput 概述](/zh-CN/build/core-features/common/input/overviews/input-overview.md)
- [GameInput 개요](/ko/build/core-features/common/input/overviews/input-overview.md)
