ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [VB.Net] 화면보호기
    VB(A) 2017. 6. 3. 20:58

    화면보호기


    플립시계가 지겨워져서 예전에 만들어둔 화면보호기가 생각나서 찾아보니 다행히 아이콘이랑 코드가 다 살아있네.

    백업은 필수.

    다시 까먹지 않기 위해 블로그에도 업로드.


    소스와 배경화면과 야후 날씨 아이콘은 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 > 0And (Abs(e.X - OldX) > 3 Or Abs(e.Y - OldY) > 3Then
                    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(NothingNothing)
     
            '날씨 클래스 및 지역 선언 - 한번만 불러오기
            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(00))
     
            '// 텍스트 드로잉
            Using Brush As Brush = New SolidBrush(Color.White)
                Dim BrushShadow As Brush = New SolidBrush(Color.FromArgb(100515151))  '그림자 브러시
                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, 150150)  '오늘의 날씨 사진
                    Using Pen As Pen = New Pen(Brush, 1)
                        G.DrawLine(Pen, New Point(WeatherX - 220150), New Point(Width - 35150)) '분리선 - 위치재선정
                    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) - 155050'일기예보 날씨 아이콘 불러오기 - 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

    cs


    ScreenSaverV2.zip

    Yahoo Weather.zip


    댓글