奇淫怪巧之给Delphi的PrintDialog增加一个页码选定范围打印的Edit
? ?在Delphi中使用PrintDialog打印對話框的時候,這個控件有三個選項,就是PrintRang那個屬性的三個選項,其中有一個選項三,讓我們自定義選擇頁碼范圍來打印。但是比較蛋疼的是,這個地方選中了之后啥子效果都沒有。無法制定自己的頁碼范圍,很是蛋疼。這里實際上應該要有一個Edit之類的編輯框的,這樣可以讓用戶輸入1,2,3-4之類的頁碼范圍來整就比較人性化了。起初以為是自己沒有指定某屬性神馬的導致,于是在控件的各個屬性中找,找的我蛋都要裂開了,都沒找出來似乎是隱藏了那個Edit的屬性。。。。無果,整開了PrintDialog的源碼看。也未發現相關的代碼。咋辦,咋辦呢。路總是人走出來的,目的就是要在這個彈出的對話框上加一個編輯框就OK了,方式很多,可以在彈出來之后,查找句柄,然后創建一個Edit,然后SetParent就上去了。這是一方面,另外一方面,就是要配合對話框上,用戶點擊上面的選項來相應的聯動這個Edit為可用或非可用狀態。這個自然也是有辦法的,我首先想到的就是Hook了,于是就用Hook整了,WH_CallWndProc消息處理過程函數的Hook,就行了。至于是要攔截神馬消息,嘿嘿,這個是WinSDK的范疇,不熟悉的人,去翻番書,或者百度一番,就可以知道是WM_Command這個消息來處理窗口中的某些控件的消息處理的。首先就是要獲取那個彈出的打印對話框的句柄了,我說過了可以用FindWindow來找。不過我這里要使用消息過程鉤子,那么自然就不要這個了,直接從鉤子中獲取對話框句柄,會更加Happy。看看PrintDialog的代碼,俺們可以知道,神馬PrintDialog,OpenDialog,FontDialog打開都要觸發WM_InitDialog這個消息,就是初始化對話框的消息。所以,第一步,俺們就攔截這個消息就 可以獲取到句柄,然后創建俺們的Edit,然后將Edit設置到對話框中,俺們需要他在的位置。第二步,就是來攔截WM_Command,然后來處理和用戶點擊的聯動處理咯。然后就是在對話框的Destroy消息中注銷Hook,釋放Edit。于是這個過程就OK了
首先在打開對話框之前,注冊我們的過程處理鉤子,必須要之前注冊,因為要攔截WM_InitDialog消息嘛
procedure TForm1.Button1Click(Sender: TObject);
beginCEdit := TEdit.CreateParented(Application.Handle);CEdit.Parent := Application.MainForm;Hok := SetWindowsHookEx(WH_CALLWNDPROC,WNDProcHook,HInstance,GetCurrentThreadId);if PrintDialog1.Execute thenbeginShowMessage(CEdit.Text);end;UnhookWindowsHookEx(HOK);FreeAndNil(CEdit);
end;
然后是鉤子函數過程處理
varDownBtnID: Integer;PrntDlgHandle: THandle;CEdit: TEdit;
function WNDProcHook(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
varmsg: PCWPSTRUCT;wNotifyCode,wID: Word;r,WinR: TRect;DwonBtnHandle: THandle;
beginif code < 0 thenResult := CallNextHookEx(Hok, code, wparam, lparam)elsebeginmsg := PCWPSTRUCT(lparam);case msg.message ofWM_INITDIALOG:beginPrntDlgHandle := msg.hwnd;DwonBtnHandle := FindWindowEx(PrntDlgHandle,0,'Button','打印范圍');Windows.SetParent(CEdit.Handle,DwonBtnHandle);GetWindowRect(DwonBtnHandle,WinR);CEdit.Visible := True;DwonBtnHandle := FindWindowEx(PrntDlgHandle,0,'Button','選定范圍(&S)');CEdit.Enabled := SendMessage(DwonBtnHandle,BM_GETCHECK,0,0) = 1;GetWindowRect(DwonBtnHandle,r);DownBtnID := GetDlgCtrlID(DwonBtnHandle);CEdit.Left := r.Right - WinR.Left;CEdit.Top := r.Top - WinR.Top;end;WM_COMMAND:beginif msg.hwnd = PrntDlgHandle thenbeginwNotifyCode := HIWORD(Msg.wparam);wID := LOWORD(Msg.wParam);if wNotifyCode = BN_CLICKED thenbeginCEdit.Enabled := wID = DownBtnIDend;end;end;WM_DESTROY:begin//UnhookWindowsHookEx(HOK);//Hok := 0;//FreeAndNil(CEdit);end;end;Result := 0;end;
end;
可見,我這里注銷了WM_Destroy中的處理。目的是因為俺們還需要返回這個Edit中的內容嘛,所以我們直接在使用完了之后注銷鉤子,釋放Edit就行了!
實現之后的效果,就是這樣的咯
轉載于:https://www.cnblogs.com/DxSoft/archive/2013/04/22/3035565.html
總結
以上是生活随笔為你收集整理的奇淫怪巧之给Delphi的PrintDialog增加一个页码选定范围打印的Edit的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这个是什么电影啊,好想看
- 下一篇: 诛仙的作者是谁啊?