화면보호기
플립시계가 지겨워져서 예전에 만들어둔 화면보호기가 생각나서 찾아보니 다행히 아이콘이랑 코드가 다 살아있네.
백업은 필수.
다시 까먹지 않기 위해 블로그에도 업로드.
소스와 배경화면과 야후 날씨 아이콘은 NAS에 있음.
까먹지 말 것.
Imports Microsoft.Win32 Imports System.Math Imports System.Xml Imports System.IO Public Class frmScr #Region "수정본" '// TODO ! // '1. 배경의 색이 밝으면 Label을 읽기 힘들어집니다. 거기에 따른 보완이 필요해보이네요. '2. 그림 파일이 저에게 없어서 그림 위치는 못잡았습니다. '3. 즐거운 코딩하세요 :) 'By 이크루스 '// TODO ! // '// 위치 정보 (어.. 실행해보면서 대충 맞췄습니다.) Private TimeX As Integer = 11 Private TimeY As Integer = 11 Private DateX As New SizeF '시간 Width 변수 Private DateY As Integer = TimeY + 100 Private TodayX As New SizeF '날짜 Width 변수 Private TodayWeatherX As Integer Private TodayWeatherY As Integer = 0 Private WeatherX As Integer Private WeatherY As Integer = TodayWeatherY + 175 Private WeatherY_Gap As Integer = 55 '// 배경화면 변수 Private Arrfiles As String() Private ImageIndex As Integer = 0 Private WallPaper As Image '// 날씨 정보 Private Weathers As Weather #Region "화면보호기 작동 중 마우스 이동 및 키보드 누르면 화면보호기 종료" Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown '화면보호기 작동 중 키 누르면 창 닫기 If sStartType = "/s" Then Close() End Sub Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove '마우스 움직이면 화면보호기 종료 Static OldX As Integer Static OldY As Integer If sStartType = "/s" Then If (OldX > 0 And OldY > 0) And (Abs(e.X - OldX) > 3 Or Abs(e.Y - OldY) > 3) Then Close() End If OldX = e.X OldY = e.Y End If End Sub #End Region Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Hide() '로딩되기 전까지 잠깐 숨기기 Dim pRegKey As RegistryKey = Registry.CurrentUser '더블버퍼링 코드. SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.DoubleBuffer, True) '레지스트리에서 화면보호기에 사용할 그림파일 불러오기(설정에서 사진파일을 먼저 선택해야함) Try pRegKey = pRegKey.OpenSubKey("Software\Screen Saver", True) Arrfiles = pRegKey.GetValue("Files") pRegKey.Close() If sStartType = "/s" Then Cursor.Hide() '화면보호기 작동 중일 땐 커서 숨기기 Catch ex As Exception '에러 발생하면 코드 종료 Exit Sub End Try 'Form의 크기에 기반한 위치 설정 TodayWeatherX = Width - 305 '오늘의 날씨 아이콘 X좌표 WeatherX = Width - 70 '최저 온도 시작 위치 '초기에 사용할 이미지 가져오기 (타이머 이벤트 불러오기) TmrImage_Tick(Nothing, Nothing) '날씨 클래스 및 지역 선언 - 한번만 불러오기 Weathers = New Weather("Busan") If Weathers.GetWeather = False Then Close() '날씨 못가져 오면 코드 종료 Show() '나타내기 End Sub Protected Overrides Sub OnPaint(e As PaintEventArgs) '// 안티 앨리어싱 설정 Dim G As Graphics = e.Graphics G.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias G.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit '// 영역 초기화 G.Clear(BackColor) '// 배경화면 드로잉 If WallPaper IsNot Nothing Then G.DrawImage(WallPaper, New Point(0, 0)) '// 텍스트 드로잉 Using Brush As Brush = New SolidBrush(Color.White) Dim BrushShadow As Brush = New SolidBrush(Color.FromArgb(100, 51, 51, 51)) '그림자 브러시 Dim F As Font = New Font(New FontFamily("Segoe UI Symbol"), 60, FontStyle.Bold) '폰트 Dim strNow As String = Now.ToString("h:mm") '현재 시간 - Width 알아내기 위함 Dim strDate As String = Now.ToString("MMM dd, ddd", Globalization.CultureInfo.CreateSpecificCulture("en-US")) '오늘 날짜 - Width 알아내서 위치 잡기 '시간 출력 G.DrawString(strNow, F, BrushShadow, New PointF(TimeX + 3, TimeY + 3)) '시간 그림자 G.DrawString(strNow, F, Brush, New PointF(TimeX, TimeY)) '시간 DateX = G.MeasureString(strNow, F) '시간의 글자 사이즈 '오늘 날짜 출력 F = New Font(New FontFamily("Segoe UI Symbol"), 25, FontStyle.Bold) TodayX = G.MeasureString(strDate, F) '오늘 날짜 글자 사이즈 가져옴 G.DrawString(strDate, F, BrushShadow, New PointF(TimeX + ((DateX.Width - TodayX.Width) / 2) + 2, DateY + 2)) '날짜 그림자 G.DrawString(strDate, F, Brush, New PointF(TimeX + ((DateX.Width - TodayX.Width) / 2), DateY)) '날짜 출력 '// 날씨 정보 드로잉 If Weathers IsNot Nothing AndAlso Weathers.Weathers IsNot Nothing Then F = New Font(New FontFamily("Segoe UI Symbol"), 50, FontStyle.Bold) '위치 재선정 G.DrawString(Weathers.Weathers(0).Temperature & "°", F, BrushShadow, New Point(TodayWeatherX + 165 + 3, TodayWeatherY + 35 + 3)) '오늘 온도 그림자 G.DrawString(Weathers.Weathers(0).Temperature & "°", F, Brush, New Point(TodayWeatherX + 165, TodayWeatherY + 35)) '오늘 온도 G.DrawImage(Image.FromFile(Weathers.Weathers(0).ImagePath), TodayWeatherX, TodayWeatherY, 150, 150) '오늘의 날씨 사진 Using Pen As Pen = New Pen(Brush, 1) G.DrawLine(Pen, New Point(WeatherX - 220, 150), New Point(Width - 35, 150)) '분리선 - 위치재선정 End Using F = New Font(New FontFamily("Segoe UI Symbol"), 15, FontStyle.Bold) For i As Integer = 1 To 5 '일기예보 텍스트에 그림자 효과 G.DrawString(Weathers.Weathers(i).LowestTemperature & "°", F, BrushShadow, New Point(WeatherX + 2, WeatherY + ((i - 1) * WeatherY_Gap) + 2)) '최저 온도 G.DrawString(Weathers.Weathers(i).HighestTemperature & "°", F, BrushShadow, New Point(WeatherX - 50 + 2, WeatherY + ((i - 1) * WeatherY_Gap) + 2)) '최고 온도 G.DrawString(Weathers.Weathers(i).Day, F, BrushShadow, New Point(WeatherX - 220 + 2, WeatherY + ((i - 1) * WeatherY_Gap) + 2)) '날짜 '일기예보 텍스트 출력 G.DrawString(Weathers.Weathers(i).LowestTemperature & "°", F, Brush, New Point(WeatherX, WeatherY + ((i - 1) * WeatherY_Gap))) '최저 온도 G.DrawString(Weathers.Weathers(i).HighestTemperature & "°", F, Brush, New Point(WeatherX - 50, WeatherY + ((i - 1) * WeatherY_Gap))) '최고 온도 G.DrawImage(Image.FromFile(Weathers.Weathers(i).ImagePath), WeatherX - 140, WeatherY + ((i - 1) * WeatherY_Gap) - 15, 50, 50) '일기예보 날씨 아이콘 불러오기 - DrawImage G.DrawString(Weathers.Weathers(i).Day, F, Brush, New Point(WeatherX - 220, WeatherY + ((i - 1) * WeatherY_Gap))) '날짜 Next End If End Using '// 메모리 정리 GC.Collect() MyBase.OnPaint(e) End Sub Private Sub TmrImage_Tick(sender As Object, e As EventArgs) Handles TmrImage.Tick '// 배경화면 바꾸기 타이머 If sStartType = "/s" Then If ImageIndex > UBound(Arrfiles) Then ImageIndex = 0 'Index가 최대 수치보다 크면 초기화 Using Stream As FileStream = New FileStream(Arrfiles(ImageIndex), FileMode.Open, FileAccess.Read) '파일을 스트림으로 오픈 (읽기 모드) Dim Temp As Image = Image.FromStream(Stream) '스트림으로부터 이미지 불러오기 WallPaper = New Bitmap(Temp, Width, Height) Temp.Dispose() '스트림으로부터 가져온 이미지 정리 (메모리 관리) End Using '파일 스트림 닫기 ImageIndex += 1 'Index 올리기 Invalidate() End If End Sub '========================================================================================== '// 날씨 정보를 담을 클래스 '[ 사용법 ] '1. Weather를 선언한다. [ex) Dim Weather As New Weather("도시 이름")] '2. GetWeather를 수행한다. [ex) If Weather.GetWeather = False Then MsgBox("에러!")] '3. Weathers에 들어있는 정보를 자유롭게 사용한다. '[ 사용법 ] Public Class Weather Sub New(CityName As String) City = CityName End Sub Public Function GetWeather() As Boolean '// 일기예보 정보를 가져올 함수, 당근쨈 님의 함수를 그대로 사용하였습니다 :) (성공하면 True, 실패하면 False를 반환) Try Dim Query As String = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text=%22fits%20" + City + "%22) and u=""c""" Dim wData As XmlDocument = New XmlDocument Dim Man As XmlNamespaceManager = New XmlNamespaceManager(wData.NameTable) Dim Channel As XmlNode '야후에서 날씨정보 불러오기 wData.Load(Query) 'XML파일 분석 Channel = wData.SelectSingleNode("query").SelectSingleNode("results").SelectSingleNode("channel") Man.AddNamespace("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0") '날씨 정보 요소들을 담을 리스트 생성 Dim Result As List(Of WeatherField) = New List(Of WeatherField) '날씨 정보를 담을 요소 생성 Dim Item As WeatherField Item = New WeatherField With Channel.SelectSingleNode("item").SelectSingleNode("yweather:condition", Man) Item.ForecastCode = .Attributes("code").Value '날씨 코드 Item.Temperature = .Attributes("temp").Value '온도 Item.Day = "Today" '날짜 Result.Add(Item) '리스트에 추가 End With '5일치 일기예보 코드 (위와 똑같이) For i As Integer = 1 To 5 Item = New WeatherField With wData.GetElementsByTagName("yweather:forecast")(i) Item.ForecastCode = .Attributes("code").Value Item.HighestTemperature = .Attributes("high").Value Item.LowestTemperature = .Attributes("low").Value Item.Day = .Attributes("day").Value Result.Add(Item) '리스트에 추가 End With Next Weathers = Result '리스트를 Weathers에 저장 Return True Catch ex As Exception '예외가 발생할 경우 MsgBox(ex.Message, vbExclamation, "ERROR") Return False End Try End Function Public City As String '도시 정보 Public Weathers As IEnumerable(Of WeatherField) '날씨 정보들을 담을 배열 변수같은 거라고 생각하시면 됩니다. Public Class WeatherField Public ForecastCode As Integer '날씨 코드 Public Temperature As Integer '온도 Public HighestTemperature As Integer '최고 온도 Public LowestTemperature As Integer '최저 온도 Public Day As String '날짜 Public ReadOnly Property ImagePath As String '이미지 경로 반환하는 읽기 전용 변수 Get Return "D:\ScreenSaver\YahooWeatherIcon\" & ForecastCode & ".png" End Get End Property End Class End Class #End Region End Class |
'VB(A)' 카테고리의 다른 글
난수 생성기(로또) (0) | 2017.06.24 |
---|---|
[VB.Net] 파일 생성일자로 폴더 생성 후 파일이동 (0) | 2017.06.04 |
지역별로 시트 생성하여 나누기 (2) | 2017.05.16 |
주식표 변경(상승, 하락 글꼴변경, 주요 금액단위 변경) (0) | 2017.05.07 |
[VB.Net] 포토갤러리 일괄 다운로더 (0) | 2017.03.05 |