吐血的天气预报

最近闲来无事,想起天气预报那个工具很不好用,所以想自己做一个。

于是顺便体验下WPF的魅力,就用WPF开始动工了。进度很快,技术上不是很难摸,

一天吧就完成了决大部分主要功能 。其实就是一个显示界面加城市选择设置部分。

 

这里也大概贴一下代码

  1. PrivateSub MainWindow_MouseLeftButtonDown(ByVal sender AsObject, ByVal e As System.Windows.Input.MouseButtonEventArgs) HandlesMe.MouseLeftButtonDown 
  2.     Me.DragMove() 
  3.  
  4. EndSub 
  5. PrivateSub MainWindow_Loaded(ByVal sender AsObject, ByVal e As System.Windows.RoutedEventArgs) HandlesMe.Loaded 
  6.  
  7.     'Dim desktopHwnd As IntPtr = GetDesktopPtr() 
  8.     'Dim ownHwnd As IntPtr = New WindowInteropHelper(Me).Handle 
  9.     'Dim result As IntPtr = SetParent(ownHwnd, desktopHwnd) 
  10.    
  11.     Dim address AsString = "" 
  12.     address = GetAddress() 
  13.  
  14.     'Dim weather() As String = ws.getWeatherbyCityName(address) 
  15.     'LoadData(weather) 
  16. EndSub 
  17. Function LoadData(ByVal weather() AsString) AsBoolean 
  18.     Try 
  19.  
  20.         Dim Today_ImageStream, Tomorrow_ImageStream, AfterTomorrow_ImageStream As FileStream 
  21.         Dim Today_Image, Tomorrow_Image, AfterTomorrow_Image AsNew BitmapImage() 
  22.         Dim gifLen AsInteger 
  23.         Dim gifName AsString 
  24.         Dim filePath AsString 
  25.  
  26.         'today 
  27.         lblTime.Content = Now.Year & "年" & Now.Month & "月" & Now.Day & "日             星期" & ConvertToChinese(Now.DayOfWeek) 
  28.         lblAddress.Content = weather(1).ToString 
  29.         Dim len AsInteger = weather(10).ToString.IndexOf("℃") - 9 
  30.         lblNow.Content = weather(10).ToString.Substring(10, len) 
  31.         lblWind.Content = weather(6).ToString.Substring(weather(6).ToString.IndexOf(" ")) 
  32.  
  33.         gifLen = weather(9).ToString.Length 
  34.         If gifLen = 5 Then 
  35.             gifName = "0" & weather(9).ToString.Replace("gif", "png"
  36.         Else 
  37.             gifName = weather(9).ToString.Replace("gif", "png"
  38.         EndIf 
  39.  
  40.         filePath = path & "images\" 
  41.         Today_ImageStream = New FileStream(filePath & gifName, FileMode.Open) 
  42.         Today_Image.BeginInit() 
  43.         Today_Image.StreamSource = Today_ImageStream 
  44.         Today_Image.EndInit() 
  45.         ImgNow.Source = Today_Image 
  46.  
  47.         lblTodayTemp.Content = weather(5).ToString.Replace("/", "--"
  48.         ImgToday.Source = Today_Image 
  49.         lblToday.Content = weather(6).ToString.Substring(0, weather(6).ToString.IndexOf(" ")) 
  50.  
  51.         'tomorrow 
  52.         If weather(9).ToString = weather(16).ToString Then 
  53.             ImgTomo.Source = Today_Image 
  54.         Else 
  55.  
  56.             gifLen = weather(16).ToString.Length 
  57.             If gifLen = 5 Then 
  58.                 gifName = "0" & weather(16).ToString.Replace("gif", "png"
  59.             Else 
  60.                 gifName = weather(16).ToString.Replace("gif", "png"
  61.             EndIf 
  62.             Tomorrow_Image = New BitmapImage() 
  63.             Tomorrow_ImageStream = New FileStream(filePath & gifName, FileMode.Open) 
  64.             Tomorrow_Image.BeginInit() 
  65.             Tomorrow_Image.StreamSource = Tomorrow_ImageStream 
  66.             Tomorrow_Image.EndInit() 
  67.             ImgTomo.Source = Tomorrow_Image 
  68.         EndIf 
  69.  
  70. lblTomo.Content = weather(13).ToString.Substring(0, weather(13).ToString.IndexOf(" ")) 
  71.         lblTomorrowTemp.Content = weather(12).ToString.Replace("/", "--"
  72.  
  73.         'the day after tomorrow 
  74.         If weather(21).ToString = weather(9).ToString Then 
  75.             ImgAfter.Source = Today_Image 
  76.         ElseIf weather(16).ToString = weather(21).ToString Then 
  77.             ImgAfter.Source = Tomorrow_Image 
  78.         Else 
  79.             gifLen = weather(21).ToString.Length 
  80.             If gifLen = 5 Then 
  81.                 gifName = "0" & weather(21).ToString.Replace("gif", "png"
  82.             Else 
  83.                 gifName = weather(21).ToString.Replace("gif", "png"
  84.             EndIf 
  85.             AfterTomorrow_Image = New BitmapImage() 
  86.             AfterTomorrow_ImageStream = New FileStream(filePath & gifName, FileMode.Open) 
  87.             AfterTomorrow_Image.BeginInit() 
  88.             AfterTomorrow_Image.StreamSource = AfterTomorrow_ImageStream 
  89.             AfterTomorrow_Image.EndInit() 
  90.             ImgAfter.Source = AfterTomorrow_Image 
  91.         EndIf 
  92.  
  93.         lblAfterTomo.Content = weather(18).ToString.Substring(0, weather(18).ToString.IndexOf(" ")) 
  94.         lblAfterTomorrowTemp.Content = weather(17).ToString.Replace("/", "--"
  95.         ReturnTrue 
  96.     Catch ex As Exception 
  97.         MsgBox(ex.ToString, MsgBoxStyle.Critical) 
  98.         ReturnFalse 
  99.     EndTry 
  100. EndFunction 
  101. Function ConvertToChinese(ByVal weekday AsInteger) AsString 
  102.     SelectCase weekday 
  103.         Case
  104.             Return"一" 
  105.         Case
  106.             Return"二" 
  107.         Case
  108.             Return"三" 
  109.         Case
  110.             Return"四" 
  111.         Case
  112.             Return"五" 
  113.         Case
  114.             Return"六" 
  115.         Case
  116.             Return"日" 
  117.  
  118.     EndSelect 
  119.  
  120.     Return"" 
  121. EndFunction 

嗯,很好,一切很顺利。我很得意,哈哈。然而就在我沾沾自喜的时候,我想这个东西应该要贴在桌面上吧,和win7小工具一样的效果。而且应该不是难事,我没放心上。

谁知道噩梦来了。不看不知道啊,原来win7的桌面是如此的诡异,分了很多层。如果没有使用aero主题的话,还好说,可是这是个废话啊,用win7的人肯定都喜欢那家伙啊。

也许我这样写不清楚,我说代码吧。开始本想很简单,我就准备使用API  SetWindowsPos ,可是事实上我太傻了,呵呵,这样只是把程序放在最后一层,但是屏蔽不了win+D这个显示桌面命令,一样不能贴住桌面(有人叫嵌入桌面)。看下代码吧,当作记录下。

  1. SetWindowPos(winHelp.Handle, HWND_BOTTOM, 0, 0, 0, 0, SetWindowPosFlags.IgnoreMove Or SetWindowPosFlags.IgnoreResize) 
  2. <DllImport("user32.dll", SetLastError:=True)> _ 
  3.     PublicFunction SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X AsInteger, ByVal Y AsInteger, ByVal cx AsInteger, ByVal cy AsInteger, ByVal uFlags As SetWindowPosFlags) AsBoolean 
  4.     EndFunction 
  5.     <Flags()> _ 
  6.     PublicEnum SetWindowPosFlags As UInteger 
  7.         ''' <summary>If the calling thread and the thread that owns the window are attached to different input queues,  
  8.         ''' the system posts the request to the thread that owns the window. This prevents the calling thread from  
  9.         ''' blocking its execution while other threads process the request.</summary> 
  10.         ''' <remarks>SWP_ASYNCWINDOWPOS</remarks> 
  11.         SynchronousWindowPosition = &H4000 
  12.         ''' <summary>Prevents generation of the WM_SYNCPAINT message.</summary> 
  13.         ''' <remarks>SWP_DEFERERASE</remarks> 
  14.         DeferErase = &H2000 
  15.         ''' <summary>Draws a frame (defined in the window's class description) around the window.</summary> 
  16.         ''' <remarks>SWP_DRAWFRAME</remarks> 
  17.         DrawFrame = &H20 
  18.         ''' <summary>Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to  
  19.         ''' the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE  
  20.         ''' is sent only when the window's size is being changed.</summary> 
  21.         ''' <remarks>SWP_FRAMECHANGED</remarks> 
  22.         FrameChanged = &H20 
  23.         ''' <summary>Hides the window.</summary> 
  24.         ''' <remarks>SWP_HIDEWINDOW</remarks> 
  25.         HideWindow = &H80 
  26.         ''' <summary>Does not activate the window. If this flag is not set, the window is activated and moved to the  
  27.         ''' top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter  
  28.         ''' parameter).</summary> 
  29.         ''' <remarks>SWP_NOACTIVATE</remarks> 
  30.         DoNotActivate = &H10 
  31.         ''' <summary>Discards the entire contents of the client area. If this flag is not specified, the valid  
  32.         ''' contents of the client area are saved and copied back into the client area after the window is sized or  
  33.         ''' repositioned.</summary> 
  34.         ''' <remarks>SWP_NOCOPYBITS</remarks> 
  35.         DoNotCopyBits = &H100 
  36.         ''' <summary>Retains the current position (ignores X and Y parameters).</summary> 
  37.         ''' <remarks>SWP_NOMOVE</remarks> 
  38.         IgnoreMove = &H2 
  39.         ''' <summary>Does not change the owner window's position in the Z order.</summary> 
  40.         ''' <remarks>SWP_NOOWNERZORDER</remarks> 
  41.         DoNotChangeOwnerZOrder = &H200 
  42.         ''' <summary>Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to  
  43.         ''' the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent  
  44.         ''' window uncovered as a result of the window being moved. When this flag is set, the application must  
  45.         ''' explicitly invalidate or redraw any parts of the window and parent window that need redrawing.</summary> 
  46.         ''' <remarks>SWP_NOREDRAW</remarks> 
  47.         DoNotRedraw = &H8 
  48.         ''' <summary>Same as the SWP_NOOWNERZORDER flag.</summary> 
  49.         ''' <remarks>SWP_NOREPOSITION</remarks> 
  50.         DoNotReposition = &H200 
  51.         ''' <summary>Prevents the window from receiving the WM_WINDOWPOSCHANGING message.</summary> 
  52.         ''' <remarks>SWP_NOSENDCHANGING</remarks> 
  53.         DoNotSendChangingEvent = &H400 
  54.         ''' <summary>Retains the current size (ignores the cx and cy parameters).</summary> 
  55.         ''' <remarks>SWP_NOSIZE</remarks> 
  56.         IgnoreResize = &H1 
  57.         ''' <summary>Retains the current Z order (ignores the hWndInsertAfter parameter).</summary> 
  58.         ''' <remarks>SWP_NOZORDER</remarks> 
  59.         IgnoreZOrder = &H4 
  60.         ''' <summary>Displays the window.</summary> 
  61.         ''' <remarks>SWP_SHOWWINDOW</remarks> 
  62.         ShowWindow = &H40 
  63.     EndEnum 

看起来很吓人,呵呵,大部分都是参数,很easy。

好吧,既然这样不行,再想,开始转战用SetParent。这个API本事不小哦,而且战斗力很强,完全可以胜任,而且已经被N多大神征服了。嗯,用吧,就是他。代码:

  1. PublicFunction GetDesktopPtr() As IntPtr 
  2.     'http://blog.csdn.net/mkdym/article/details/7018318 
  3.     ' 情况一 
  4.     Dim hwndWorkerW As IntPtr = IntPtr.Zero 
  5.     Dim hShellDefView As IntPtr = IntPtr.Zero 
  6.     Dim hwndDesktop As IntPtr = IntPtr.Zero 
  7.  
  8.     Dim hProgMan As IntPtr = FindWindow("ProgMan", Nothing
  9.  
  10.     If hProgMan <> IntPtr.Zero Then 
  11.         hShellDefView = FindWindowEx(hProgMan, IntPtr.Zero, "SHELLDLL_DefView", Nothing
  12.         If hShellDefView <> IntPtr.Zero Then 
  13.             'hwndDesktop = FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", "FolderView") 
  14.             hwndDesktop = FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", Nothing
  15.         EndIf 
  16.     EndIf 
  17.     If hwndDesktop <> IntPtr.Zero Then 
  18.         Return hwndDesktop 
  19.     EndIf 
  20.  
  21.     ' 情况二 
  22.     While hwndDesktop = IntPtr.Zero 
  23.         '必须存在桌面窗口层次   
  24.         hwndWorkerW = FindWindowEx(IntPtr.Zero, hwndWorkerW, "WorkerW", Nothing
  25.         '获得WorkerW类的窗口   
  26.         If hwndWorkerW = IntPtr.Zero Then 
  27.             ExitWhile 
  28.         EndIf 
  29.         '未知错误 
  30.         hShellDefView = FindWindowEx(hwndWorkerW, IntPtr.Zero, "SysListView32", Nothing
  31.         If hShellDefView = IntPtr.Zero Then 
  32.             Continue While 
  33.         EndIf 
  34.         hwndDesktop = FindWindowEx(hShellDefView, IntPtr.Zero, "SysListView32", Nothing
  35.     EndWhile 
  36.     Return hwndDesktop 
  37. EndFunction 
  38.  
  39. DeclareFunction SetActiveWindow Lib"user32"Alias"SetActiveWindow" (ByVal hwnd As IntPtr) As IntPtr 
  40. DeclareFunction ShowWindow Lib"user32"Alias"ShowWindow" (ByVal hwnd As IntPtr, ByVal nCmdShow As IntPtr) As IntPtr 
  41.  
  42. PublicDeclareFunction GetPrivateProfileString Lib"KERNEL32.DLL"Alias"GetPrivateProfileStringA" ( _ 
  43. ByVal lpAppName AsString, _ 
  44. ByVal lpKeyName AsString, ByVal lpDefault AsString, _ 
  45. ByVal lpReturnedString As System.Text.StringBuilder, ByVal nSize AsInteger, _ 
  46. ByVal lpFileName AsString) AsInteger 
  47.  
  48.  
  49. PublicDeclareFunction WritePrivateProfileString Lib"KERNEL32.DLL"Alias"WritePrivateProfileStringA" ( _ 
  50. ByVal lpAppName AsString, _ 
  51. ByVal lpKeyName AsString, _ 
  52. ByVal lpString AsString, _ 
  53. ByVal lpFileName AsString) AsInteger 
  54.  
  55. <DllImport("User32.dll", EntryPoint:="FindWindowEx")> _ 
  56. PublicFunction FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpClassName AsString, ByVal lpWindowName AsString) As IntPtr 
  57. EndFunction 
  58.  
  59. <DllImport("user32.dll", EntryPoint:="FindWindow")> _ 
  60. PublicFunction FindWindow(ByVal lpClassName AsString, ByVal lpWindowName AsString) As IntPtr 
  61. EndFunction 
  62. <DllImport("user32.dll", EntryPoint:="GetWindow")> _ 
  63. PublicFunction GetWindow(ByVal hwnd As IntPtr, ByVal wCmd As IntPtr) As IntPtr 
  64. EndFunction 
  65.  
  66. <DllImport("user32.dll", EntryPoint:="SetParent")> _ 
  67. PublicFunction SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr 
  68. pre class="vb" name="code">    EndFunction 

  1. '这三句就看可以使用了 

  1. Dim desktopHwnd As IntPtr = GetDesktopPtr() 
  2. Dim ownHwnd As IntPtr = New WindowInteropHelper(Me).Handle 
  3. Dim result As IntPtr = SetParent(ownHwnd, desktopHwnd) 


里面有熟悉的代码和注释?别奇怪,是COPY来的,呵呵。运行代码后,觉得很牛逼吧,不错,是贴上去了。可是我想看看换个桌面图片看看什么效果。我靠,一换完蛋了,刚刚那个效果不见了。赶紧还原动作啊,折腾了半天,毛都不见了。赶紧去问娘啊,哥啊的,度娘说,很多人都是这样。遇到AERO主题下,由于有任务栏下面那个小窗体,窗体句柄不太好找了,能不能成功可能就要看人品和运气了。算了,不行咋办?听说还可以消息拦截,要不试下?好吧,我再找度娘。得到代码几行,经验+100。

  1. 'Dim winHelp As WindowInteropHelper = New WindowInteropHelper(Me) 
  2.    'Protected Overrides Sub OnSourceInitialized(ByVal e As EventArgs) 
  3.    '    MyBase.OnSourceInitialized(e) 
  4.    '    Dim hwndSource As HwndSource = TryCast(PresentationSource.FromVisual(Me), HwndSource) 
  5.    '    If hwndSource IsNot Nothing Then 
  6.    '        hwndSource.AddHook(New HwndSourceHook(AddressOf Me.WndProc)) 
  7.    '    End If 
  8.    'End Sub 
  9.    'Protected Overridable Function WndProc(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr 
  10.    '    Return IntPtr.Zero 
  11.    'End Function 
  12.    'Protected Overridable Function WndProc(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr 
  13.    '    'If msg = WM_SIZE Then 
  14.    '    'MsgBox("") 
  15.    '    'If WindowState = WindowState.Minimized Then 
  16.  
  17.    '    '    SetWindowPos(winHelp.Handle, HWND_BOTTOM, 0, 0, 0, 0, SetWindowPosFlags.IgnoreMove Or SetWindowPosFlags.IgnoreResize) 
  18.    '    '    handled = True 
  19.    '    'End If 
  20.    '    WindowState = WindowState.Maximized 
  21.  
  22.    '    'End If 
  23.  
  24.  
  25.  
  26.    '    Return IntPtr.Zero 
  27.  
  28.    'End Function 

上面的代码有很多是注释了N遍,我也没恢复过来,可见我调的多认真,哈哈。哎,上面的代码主要就是取拦截消息,我的确也狠狠研究了下windows消息。结果也很失望,消息是拦截掉了,可是不知道怎么屏蔽掉这个显示桌面让他最小化的。什么办法都用了,只有那个windowstate给点脸,不过效果不太好,其他都不理我。   这个时候我想放弃了。可是难得有时间想做个东西啊,好不甘心啊,玛德,睡觉都在想着他,可怜吧。我最后想回头用GDI+来试试,实在不行用鼠标穿透看看。结果是行了,哈哈,赶紧做吧。我哼哧哼哧的又搞了一天,好了,试试效果吧。哎,那家伙怎么一直在最上面啊,怎么都盖不住啊,显示桌面是没有效果,但是其他的文件打开还是被他挡住了啊。我回头一看,原来我用了topmost,擦,难怪显示桌面萎了。这时候我好像骂人啊,为了这个功能花了几天时间没磨出一个屁来。而且用win7的人都知道,任务栏右下角还有个按钮显示桌面的,那个功能和win+D的原理还不一样。哎,彻底失望了。

  GDI+的代码就不贴了,没啥意思。写这个主要想记录下我这几天的经历,也留下一点代码,我觉得蛮有用的。现在这个天气预报是做好了,就是不能完成win7小工具那样贴在桌面上的功能,就自己辛苦点,再按下显示桌面显示吧。没办法了。如果有人知道怎么做,也指点下我吧,谢谢。那个东西我传上去了,有兴趣的可以下载看看。

忘记告诉你们了,上面提到的方法在XP下完全没有问题,win7下是选择性的,哈哈。

下载路径:http://download.csdn.net/detail/machong8183/4262823

posted @ 2012-04-26 17:17  五画  Views(286)  Comments(0Edit  收藏  举报