1. 程式人生 > >利用桌面背景進行任務管理

利用桌面背景進行任務管理

背景

作為一個輕微強迫症患者,我一直以來的桌面都是這樣的:

(如何隱藏桌面圖示、開始選單、托盤圖片不在本文討論範圍。。。)
但是記性一直不是很好的我很希望有個可以作為提醒的東西可以放到桌面上。一開始我投靠了Windows自帶的便籤,當然這個功能還是很好用的,但是我不能容忍出現這種情況:

如果用這個便籤 就會在工作列多一個專案 而且在alt+tab的時候會多一個選項(smart link一定會被我弄掉的!!!),這樣每次切換的時候都可能浪費幾毫秒。。。
我就是想要一個提醒嘛。。。也不用很好看。。所以我就準備在自己的桌面桌布上做文章
一開始 我就直接用畫圖添加了。。後來實在太麻煩 就寫了個程式來進行更改,沒想到在其中還學到了一些新的技術,就總結一些好了。。
啊。。先展示一些結果吧。。目前我的桌面如下:

具體實現

第一步是對圖片進行新增文字的處理

其實這裡沒什麼難點,主要是計算文字的位置以及調整文字的大小。
JDK裡有自帶的圖片處理類,這裡主要用到的是java.awt.Graphics2D裡的drawString()方法。
drawString(String str, int x, int y) 可以將字串str新增到圖片(x,y)位置。需要注意的是:對圖片進行處理的時候座標是反轉的第一象限。
利用Font、FontRenderContext、Rectangle2D可以設定畫筆Graphics2D的字型大小以及獲得文字的寬度和高度(這一點很重要)
之後就是一步步計算文字的位置,此處省略。。。
主要的程式碼如下:

    public static void drawText(Graphics2D g, String logoText, int line) {
        // 設定顏色
        g.setColor(Color.WHITE);
        // 設定 Font
        Font font = new Font("黑體", Font.BOLD, 30);
        g.setFont(font);
        FontRenderContext context = g.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(logoText, context);
        double
x = (width - bounds.getWidth()) - 10; double y = -line * 1.5 * bounds.getY(); g.drawString(logoText, (int) x, (int) y); }

第二步是將生成的圖片設定為桌面背景(這兒有大坑)

因為更改桌面背景的時候,需要重新整理桌面,Java本身是不能對Windows進行操作的,所以這裡需要利用JNA呼叫DLL檔案裡的原生函式進行處理。
有關JNA的簡介,可以去看一下http://www.doc88.com/p-31975835542.html 這篇文章
利用user32.dll裡的SystemParametersInfoA函式 就可以向Windows系統傳送更新桌面桌布的訊息了,這裡需要設定uiAction為0x0014即十進位制的20。
詳情可以看一下微軟給的文件
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724947(v=vs.85).aspx
這兒的坑在哪呢?在這兒:
使用SystemParametersInfoA函式設定桌面桌布的時候,只能使用JPG格式的圖片!!而我們正常使用的右鍵設定為桌面的時候用的是stobject.dll。。。而微軟的文件裡也沒有給出圖片格式的說明~所以大部分的時間都是在調這個bug…….
下面是主要的程式碼:

    public static boolean setBackPic() throws IOException {
        Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "Control Panel\\Desktop", "Wallpaper", path);
        Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "Control Panel\\Desktop", "WallpaperStyle", "0");
        Advapi32Util.registrySetStringValue(WinReg.HKEY_CURRENT_USER, "Control Panel\\Desktop", "TileWallpaper", "0");
        int SPI_SETDESKWALLPAPER = 0x0014;
        int SPIF_UPDATEINIFILE = 0x0001;
        int SPIF_SENDWININICHANGE = 0x0002;

        return MyUser32.INSTANCE.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE |
                SPIF_SENDWININICHANGE);
    }

下個版本計劃

目前還只能通過eclipse進行處理 下一步要做成UI介面的
對圖片的處理耗時有點長 下個版本要優化!!