VB.NET GDI+ 天气预报

前端之家收集整理的这篇文章主要介绍了VB.NET GDI+ 天气预报前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

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

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

这里也大概贴一下代码

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


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

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

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

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

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

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

  1. Public Function 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,"SysListView32","FolderView")
  14. hwndDesktop = FindWindowEx(hShellDefView,Nothing)
  15. End If
  16. End If
  17. If hwndDesktop <> IntPtr.Zero Then
  18. Return hwndDesktop
  19. End If
  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. Exit While
  28. End If
  29. '未知错误
  30. hShellDefView = FindWindowEx(hwndWorkerW,Nothing)
  31. If hShellDefView = IntPtr.Zero Then
  32. Continue While
  33. End If
  34. hwndDesktop = FindWindowEx(hShellDefView,Nothing)
  35. End While
  36. Return hwndDesktop
  37. End Function
  38.  
  39. Declare Function SetActiveWindow Lib "user32" Alias "SetActiveWindow" (ByVal hwnd As IntPtr) As IntPtr
  40. Declare Function ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As IntPtr,ByVal nCmdShow As IntPtr) As IntPtr
  41.  
  42. Public Declare Function GetPrivateProfileString Lib "KERNEL32.DLL" Alias "GetPrivateProfileStringA" ( _
  43. ByVal lpAppName As String,_
  44. ByVal lpKeyName As String,ByVal lpDefault As String,_
  45. ByVal lpReturnedString As System.Text.StringBuilder,ByVal nSize As Integer,_
  46. ByVal lpFileName As String) As Integer
  47.  
  48.  
  49. Public Declare Function WritePrivateProfileString Lib "KERNEL32.DLL" Alias "WritePrivateProfileStringA" ( _
  50. ByVal lpAppName As String,_
  51. ByVal lpKeyName As String,_
  52. ByVal lpString As String,_
  53. ByVal lpFileName As String) As Integer
  54.  
  55. <DllImport("User32.dll",EntryPoint:="FindWindowEx")> _
  56. Public Function FindWindowEx(ByVal hwndParent As IntPtr,ByVal hwndChildAfter As IntPtr,ByVal lpClassName As String,ByVal lpWindowName As String) As IntPtr
  57. End Function
  58.  
  59. <DllImport("user32.dll",EntryPoint:="FindWindow")> _
  60. Public Function FindWindow(ByVal lpClassName As String,ByVal lpWindowName As String) As IntPtr
  61. End Function
  62. <DllImport("user32.dll",EntryPoint:="GetWindow")> _
  63. Public Function GetWindow(ByVal hwnd As IntPtr,ByVal wCmd As IntPtr) As IntPtr
  64. End Function
  65.  
  66. <DllImport("user32.dll",EntryPoint:="SetParent")> _
  67. Public Function SetParent(ByVal hWndChild As IntPtr,ByVal hWndNewParent As IntPtr) As IntPtr
  68.     End Function
             '这三句就看可以使用了
  69.          Dim desktopHwnd As IntPtr = GetDesktopPtr()
  70.          Dim ownHwnd As IntPtr = New WindowInteropHelper(Me).Handle
  71.          Dim result As IntPtr = SetParent(ownHwnd,desktopHwnd)
  72.   
  73.  
  74. 里面有熟悉的代码和注释?别奇怪,是COPY来的,呵呵。运行代码后,觉得很牛逼吧,不错,是贴上去了。可是我想看看换个桌面图片看看什么效果。我靠,一换完蛋了,刚刚那个效果不见了。赶紧还原动作啊,折腾了半天,毛都不见了。赶紧去问娘啊,哥啊的,度娘说,很多人都是这样。遇到AERO主题下,由于有任务栏下面那个小窗体,窗体句柄不太好找了,能不能成功可能就要看人品和运气了。算了,不行咋办?听说还可以消息拦截,要不试下?好吧,我再找度娘。得到代码几行,经验+100

  75.  'Dim winHelp As WindowInteropHelper = New WindowInteropHelper(Me)
  76.     'Protected Overrides Sub OnSourceInitialized(ByVal e As EventArgs)
  77.     '    MyBase.OnSourceInitialized(e)
  78.     '    Dim hwndSource As HwndSource = TryCast(PresentationSource.FromVisual(Me),HwndSource)
  79.     '    If hwndSource IsNot Nothing Then
  80.     '        hwndSource.AddHook(New HwndSourceHook(AddressOf Me.WndProc))
  81.     '    End If
  82.     'End Sub
  83.     '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
  84.     '    Return IntPtr.Zero
  85.     'End Function
  86.     'Protected Overridable Function WndProc(ByVal hwnd As IntPtr,ByRef handled As Boolean) As IntPtr
  87.     '    'If msg = WM_SIZE Then
  88.     '    'MsgBox("")
  89.     '    'If WindowState = WindowState.Minimized Then
  90.     '    '    SetWindowPos(winHelp.Handle,SetWindowPosFlags.IgnoreMove Or SetWindowPosFlags.IgnoreResize)
  91.     '    '    handled = True
  92.     '    'End If
  93.     '    WindowState = WindowState.Maximized
  94.     '    'End If
  95.     '    Return IntPtr.Zero
  96.     'End Function
  97.  
  98. 上面的代码有很多是注释了N遍,我也没恢复过来,可见我调的多认真,哈哈。哎,上面的代码主要就是取拦截消息,我的确也狠狠研究了下windows消息。结果也很失望,消息是拦截掉了,可是不知道怎么屏蔽掉这个显示桌面让他最小化的。什么办法都用了,只有那个windowstate给点脸,不过效果不太好,其他都不理我。

  99. 这个时候我想放弃了。可是难得有时间想做个东西啊,好不甘心啊,玛德,睡觉都在想着他,可怜吧。我最后想回头用GDI+来试试,实在不行用鼠标穿透看看。结果是行了,哈哈,赶紧做吧。我哼哧哼哧的又搞了一天,好了,试试效果吧。哎,那家伙怎么一直在最上面啊,怎么都盖不住啊,显示桌面是没有效果,但是其他的文件打开还是被他挡住了啊。我回头一看,原来我用了topmost,擦,难怪显示桌面萎了。这时候我好像骂人啊,为了这个功能花了几天时间没磨出一个屁来。而且用win7的人都知道,任务栏右下角还有个按钮显示桌面的,那个功能和win+D的原理还不一样。哎,彻底失望了。

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

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

  102. 点击下载程序

  103.  
  104.  

猜你在找的VB相关文章