我從微軟編寫的網站下載「Extensible Dialogs Source」(C#使用P/Invoke),以顯示如何將Windows Forms控件放入內部常用文件對話框之一。 (如:添加預覽功能)。 這個項目有測試客戶端代碼,它是打開一個對話框,一旦你點擊一張圖片,你就可以在對話框的右側預覽圖片。 測試客戶端代碼在中工作良好32位構建,但不在64位構建。由FileOpenDialog生成的通知消息生成32位構建不生成64位
一些調試後,我發現這是因爲在64位的版本,從
[DllImport("ComDlg32.dll", CharSet = CharSet.Unicode)]
internal static extern bool GetOpenFileName(ref OpenFileName ofn);
CDN_SELCHANGE通知消息不能被識別或不正確的在C#代碼處理。
// WM_NOTIFY - we're only interested in the CDN_SELCHANGE notification message
// we grab the currently-selected filename and fire our event
case WindowMessage.Notify:
{
IntPtr ipNotify = new IntPtr(lParam);
OfNotify ofNot = (OfNotify)Marshal.PtrToStructure(ipNotify, typeof(OfNotify));
UInt16 code = ofNot.hdr.code;
if(code == CommonDlgNotification.SelChange)
{
// This is the first time we can rely on the presence of the content panel
// Resize the content and user-supplied panels to fit nicely
FindAndResizePanels(hWnd);
// get the newly-selected path
IntPtr hWndParent = NativeMethods.GetParent(hWnd);
StringBuilder pathBuffer = new StringBuilder(_MAX_PATH);
UInt32 ret = NativeMethods.SendMessage(hWndParent, CommonDlgMessage.GetFilePath, _MAX_PATH, pathBuffer);
string path = pathBuffer.ToString();
// copy the string into the path buffer
UnicodeEncoding ue = new UnicodeEncoding();
byte[] pathBytes = ue.GetBytes(path);
Marshal.Copy(pathBytes, 0, _fileNameBuffer, pathBytes.Length);
// fire selection-changed event
if(SelectionChanged != null) SelectionChanged(path);
}
return IntPtr.Zero;
}
即使我在打開文件對話框選擇不同的文件,ofNot.hdr.code
始終爲0,其結果是,應用程序從未if(code == CommonDlgNotification.SelChange)
後跑入代碼塊。 任何人都可以使這個測試樣本工作在64位構建?提前致謝!
示例代碼下載鏈接:ExtensibleDialogsSource.msi
這是擴展文件對話框的錯誤方法。使用IFileDialogCustomize。 –
我的水晶球說OfNotify宣言是錯誤的。例如,NMHDR.idFrom很容易犯錯,應該是IntPtr。它對於NMHDR.code是可見的,它不是UInt16。 –
是的,你是對的!非常感謝! –