FastReport呼叫程序控制代碼,設定視窗置頂
應用場景
在使用第三方列印外掛,FastReport時,選擇列印xps,點選列印,彈出檔案另存為對話方塊,但是此對話方塊不會出現在軟體的最前面,而且會一直佔用程序,點選軟體介面出現假死情況。解決方案
思路1.設定關閉列印進度視窗,此視窗會一直置頂,而且取消按鈕失效
2.列印前開啟執行緒進行輪詢獲取列印程序
3.根據程序獲取視窗控制代碼,設定視窗位置為最前
4.結束輪詢
實現
1.關閉列印進度視窗
設定ShowProgress為false,具體參考http://blog.csdn.net/yijunwanghaha/article/details/60761033
2.啟動輪詢
據觀察,當彈出檔案另存為視窗時,系統會多出名為splwow64的程序,我們可以通過此程序實現置頂功能,但是由於我們不知道使用者何時點選window系統的列印按鈕,所以需要在程式執行FastReport列印前啟動一個輪詢,獲取程序,實現視窗置頂功能
// 列印是否完成
static bool isPrintCompleted = false;
// 設定視窗置頂
private static void SetWindowTop()
{
Task.Run(() =>
{
// 非同步輪詢實現視窗置頂
while (!isPrintCompleted)
{
// 獲取視窗置頂
isPrintCompleted = WindowClass.SetWindowTop();
Thread.Sleep(100);
}
});
}
3.根據程序獲取視窗控制代碼,設定視窗位置為最前首先我們需要獲取程式名為splwow64的程序控制代碼
獲取到控制代碼後,通過user32.dll介面設定置頂string processName = "splwow64"; Process[] processes = Process.GetProcesses(); foreach (Process process in processes) { if (process.ProcessName == processName) { // 根據程序Id獲取程序視窗控制代碼 IntPtr intPtr = process.MainWindowHandle; while (intPtr == IntPtr.Zero) // 這裡要判斷控制代碼為0的情況,只有彈出另存為窗口才會有值 { Thread.Sleep(100); // 重新獲取控制代碼 intPtr = process.MainWindowHandle; } } }
引用user32函式
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
public static extern IntPtr SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
// 恢復原來視窗,並觸發視窗
public const int SW_RESTORE = 9;
實現
// 顯示視窗
ShowWindow(intPtr, SW_RESTORE);
// 視窗置頂
SetWindowPos(intPtr, -1, 0, 0, 0, 0, 1 | 2);
SetForegroundWindow(intPtr);
整體程式碼Internal calss PrintClass
{
// 列印是否完成
static bool isPrintCompleted = false;
private static void SetWindowTop()
{
Task.Run(() =>
{
// 非同步輪詢獲取視窗置頂
while (!isPrintCompleted)
{
// 獲取視窗置頂
isPrintCompleted = WindowClass.WindowPos();
Thread.Sleep(100);
}
});
}
public static void Print()
{
isPrintCompleted = false;
SetWindowTop()
r.PrintPrepared();
r.Print();
isPrintCompleted = true;
}
}
internal class WindowClass
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(PrintHelper));
// 該函式改變一個子視窗,彈出式視窗式頂層視窗的尺寸,位置和Z序
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
// 該函式將建立指定視窗的執行緒設定到前臺,並且啟用該視窗
[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
public static extern IntPtr SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
// 恢復原來視窗,並觸發視窗
public const int SW_RESTORE = 9;
/// <summary>
/// 設定列印視窗置頂
/// </summary>
/// <returns></returns>
public static bool SetWindowTop()
{
try
{
// 程序名稱
string processName = "splwow64";
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
if (process.ProcessName == processName)
{
// 根據程序Id獲取程序視窗控制代碼
IntPtr intPtr = process.MainWindowHandle;
while (intPtr == IntPtr.Zero)
{
Thread.Sleep(100);
// 重新獲取控制代碼
intPtr = process.MainWindowHandle;
}
// 顯示視窗(有時視窗被最小化/隱藏)
ShowWindow(intPtr, SW_RESTORE);
// 更改視窗的Zorder,SetWindowPos使之最上
SetWindowPos(intPtr, -1, 0, 0, 0, 0, 1 | 2);
// 置頂啟用
SetForegroundWindow(intPtr);
return true;
}
}
}
catch (Exception ex) { Logger.Info(ex.ToString()); }
return false;
}
}
應用延伸
此方式可實現多種視窗呈現順序,排序等情況相關技術資料
相關推薦
FastReport呼叫程序控制代碼,設定視窗置頂
應用場景 在使用第三方列印外掛,FastReport時,選擇列印xps,點選列印,彈出檔案另存為對話方塊,但是此對話方塊不會出現在軟體的最前面,而且會一直佔用程序,點選軟體介面出現假死情況。 解決方案 思路1.設定關閉列印進度視窗,此視窗會一直置頂,而且取消按鈕失效2.列印
C# 呼叫win32API 獲取程序控制代碼 有毛用???
private void button2_Click(object sender, EventArgs e) { Process[] ProceddingCon = Process.GetProcesses(); //獲得所有程序 Int
根據程序名取程序ID,控制代碼,最前端顯示
#include <Psapi.h>(需連結Psapi.Lib) DWORD m_dwTstObjID;HWND m_lmshwnd = NULL; //回撥函式,根據程序ID獲得程序控制代碼 BOOL CALLBACK EnumWindowsProc(HW
MFC 獲取當前視窗控制代碼,或者父子視窗控制代碼
父子視窗 在子視窗中,需要用到父視窗的控制代碼: AfxGetMainWnd()->m_hWnd 注:在父視窗中,也可以這麼用來呼叫自己視窗的控制代碼 在子視窗中,需要用到自己視窗的控制代碼 ChildDlg *pChildDlg ; pChildDlg->m_h
獲取ArcMap視窗控制代碼,通過WinAPI獲取工作空間中點選要素的系統桌面座標
這裡用了個“桌面座標”,是希望區分一下ArcGis的“螢幕座標”(與之對應的還有一個“地理座標”)。 什麼是“螢幕座標”呢?使用ITool介面的OnMouseDown方法獲取的“x,y”值即是,其原點值在“工作空間”窗體左上角。 什麼是我所稱謂的“工作空間”呢?它是資料編輯區域,用Spy++檢視一下其窗體
C# winform winApi 根據傳入handle 控制代碼獲取 其它視窗,如:使用中的子視窗、同級視窗等。
//根據傳入的視窗控制代碼,獲取到同級、頂級、低階的視窗,根據GetWindowCmd 傳入的不同獲取也不同,詳細看GetWindowCmd 類說明 [DllImport("user32.dll", SetLastError = true)] static exter
lsof-檢視程序控制代碼
[email protected]:~# lsof COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1
【2018.05.11】python3.6+selenium 多視窗,控制代碼,切換
#coding = utf-8 ''' 多視窗控制代碼 獲取 切換 ''' from selenium import webdriver import time driver = webdriver.Chrome() driver.get("http://home.zhiyoo.com/") d
建立執行緒後為什麼關閉了執行緒控制代碼,執行緒還是可以執行?
主執行緒只要擁有執行緒控制代碼,事後就可以對執行緒執行某些操作,比如查詢執行緒狀態等等,靠的就是控制代碼,如果沒有控制代碼,系統就無從知道要查的是那個執行緒的狀態。但保持這個控制代碼不關閉,並不是執行緒執行的條件。 &nbs
C++通過程序名獲取程序控制代碼
記錄下一段,比較常用的程式碼。 // 強殺定期刪除程序 void CDogThread::Quit() { // 結束強殺定期刪除程序 HANDLE hProcess = GetProcessHa
程序控制代碼HANDLE獲得程序主視窗的控制代碼HWND
一個程序可以擁有很多主視窗,也可以不擁有主視窗,所以這樣的函式是不存在的,所幸的是,相反的函式是有的。所以我們可以呼叫EnumWindows來判斷所有的視窗是否屬於這個程序。 typedef struct tagWNDINFO { DWORD dwProc
如何查詢窗體,獲取窗體的控制代碼,Hwnd FindWindow函式
/*CWnd::FindWindowstatic CWnd* PASCAL FindWindow( LPCTSTR lpszClassName, LPCTSTRlpszWindowNa- me );返回值:標識了具有指定的類名或視窗名的視窗。如果沒有找到這樣的視窗,則返回N
根據程序控制代碼 獲得可執行檔案路徑 的幾種方法
通過程序控制代碼,獲得可執行檔案的路徑,主要有以下幾種方法: 第一種方法:也是最常用的方法,是通過GetModuleFileNameEx函式獲得可執行檔案的模組路徑,這個函式從Windows NT 4.0開始到現在的Vista系統都能使用,向後相容性比較好。 【函式
python得到qq控制代碼,並顯示在前臺
# 匯入模組 import win32gui win = win32gui.FindWindow(None, u'張三') # 將視窗調到前臺 win32gui.ShowWindow(win, w
Windows程序控制代碼數限制
GDIProcessHandleQuota項設定GDI控制代碼數量,預設值為2710(16進位制)/10000(10進位制),該值的允許範圍為 256 ~ 16384 ,將其調整為大於預設的10000的值。如果您的系統配置了2G或更多內容,不妨將其設定為允許的最大值 16384(10進位制);USERProc
在java程式中如何能獲取到另一個程式的windows控制代碼,又如何使用這個控制代碼向這個視窗傳送訊息
import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.W
[Delphi]如何通過程序控制代碼判斷該程序是否已退出?
GetExitCodeProcess 看似可以,但是仔細看MSDN,有這麼一句話:“Warning If a process happens to return STILL_ACTIVE (259) as an error code, applications th
模組控制代碼和程序控制代碼的區別?
在WINDOWS下,模組指的是EXE和DLL等資料載入到記憶體中的影像,模組控制代碼又是比較特殊的,它跟一般的控制代碼不一樣,模組控制代碼指向的就是EXE和DLL等的在記憶體的位置(就是指向它們的資料起始位置);程序控制代碼只是WINDOWS用來標識某個程
根據檔案控制代碼,獲取檔名(轉載)
#include <windows.h>#include <stdio.h>#include <tchar.h>#include <string.h>#include <psapi.h>#define BUFSIZE
通過程序名得到程序控制代碼(tlhelp的方法)(ring3)
這個是因為我在網上搜只搜到列舉控制代碼的感覺很不方便,所以寫下這個僅供參考 HANDLE sub2(WCHAR* processname) {PROCESSENTRY32 pe32 = { 0 };// 在本程序中拍一個所有程序的快照HANDLE hModuleSnap