protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam) { if (msg == NativeMethods.WM_NOTIFY) { dialogHWnd = UnsafeNativeMethods.GetParent(new HandleRef(null, hWnd)); try { UnsafeNativeMethods.OFNOTIFY notify = (UnsafeNativeMethods.OFNOTIFY)UnsafeNativeMethods.PtrToStructure(lparam, typeof(UnsafeNativeMethods.OFNOTIFY)); switch (notify.hdr_code) { case -601: /* CDN_INITDONE */ MoveToScreenCenter(dialogHWnd); break; case -602: /* CDN_SELCHANGE */ NativeMethods.OPENFILENAME_I ofn = (NativeMethods.OPENFILENAME_I)UnsafeNativeMethods.PtrToStructure(notify.lpOFN, typeof(NativeMethods.OPENFILENAME_I)); // Get the buffer size required to store the selected file names. int sizeNeeded = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, dialogHWnd), 1124 /*CDM_GETSPEC*/, System.IntPtr.Zero, System.IntPtr.Zero); if (sizeNeeded > ofn.nMaxFile) { // A bigger buffer is required. try { int newBufferSize = sizeNeeded + (FILEBUFSIZE / 4); // Allocate new buffer CharBuffer charBufferTmp = CharBuffer.CreateBuffer(newBufferSize); IntPtr newBuffer = charBufferTmp.AllocCoTaskMem(); // Free old buffer Marshal.FreeCoTaskMem(ofn.lpstrFile); // Substitute buffer ofn.lpstrFile = newBuffer; ofn.nMaxFile = newBufferSize; this.charBuffer = charBufferTmp; Marshal.StructureToPtr(ofn, notify.lpOFN, true); Marshal.StructureToPtr(notify, lparam, true); } catch { // intentionaly not throwing here. } } this.ignoreSecondFileOkNotification = false; break; case -604: /* CDN_SHAREVIOLATION */ // See VS Whidbey 95342. When the selected file is locked for writing, // we get this notification followed by *two* CDN_FILEOK notifications. this.ignoreSecondFileOkNotification = true; // We want to ignore the second CDN_FILEOK this.okNotificationCount = 0; // to avoid a second prompt by PromptFileOverwrite. break; case -606: /* CDN_FILEOK */ if (this.ignoreSecondFileOkNotification) { // We got a CDN_SHAREVIOLATION notification and want to ignore the second CDN_FILEOK notification if (this.okNotificationCount == 0) { this.okNotificationCount = 1; // This one is the first and is all right. } else { // This is the second CDN_FILEOK, so we want to ignore it. this.ignoreSecondFileOkNotification = false; UnsafeNativeMethods.SetWindowLong(new HandleRef(null, hWnd), 0, new HandleRef(null, NativeMethods.InvalidIntPtr)); return(NativeMethods.InvalidIntPtr); } } if (!DoFileOk(notify.lpOFN)) { UnsafeNativeMethods.SetWindowLong(new HandleRef(null, hWnd), 0, new HandleRef(null, NativeMethods.InvalidIntPtr)); return(NativeMethods.InvalidIntPtr); } break; } } catch { if (dialogHWnd != IntPtr.Zero) { UnsafeNativeMethods.EndDialog(new HandleRef(this, dialogHWnd), IntPtr.Zero); } throw; } } return(IntPtr.Zero); }