반응형

아래 링크의 프로그램과 비슷하지만 바탕화면(Desktop)이 아닌 폼에 이미지를 출력해 바탕화면에 출력한 것처럼 보이는 프로그램을 만들어 보자.

 

2021.11.27 - [C#] - C# Desktop Image Display Program - 바탕화면 이미지 출력 프로그램

 

폼과 버튼을 적당히 배치한다.

폼에는
FormBorderStyle - None
ShowInTaskBar - False
TopMost - True
등의 조건을 준다.

 

이미지, 음악등 리소스를 추가한다.

 

Images.zip
2.32MB

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using System.Runtime.InteropServices;
using System.Media;
 
namespace Christmas
{
    public partial class Form1 : Form
    {
        int screenWidth;
        int screenHeight;
 
        Random R;   // 눈 위치 지정
        int snowflakeCount;
 
        // 대부분 이미지 파일은 화면과 해상도가 달라서 작거나 크게 표시된다.
        // Image로 받지 말고 비트맵으로 변환해 사용하면 된다.
        Bitmap[] snowflakes;
        Bitmap tree;                
        Bitmap leftTop;
        Bitmap rightTop;
        Bitmap rightDeer;
        Bitmap cane;
        Bitmap bulb;
        Bitmap snowMan;
        Bitmap merry;
        Bitmap screen;  // 프로그램 시작 전 전체 화면
        Bitmap buffer;  // 더블 버퍼링
 
        public Form1()
        {
            InitializeComponent();
 
            screenWidth = Screen.PrimaryScreen.Bounds.Width;
            screenHeight = Screen.PrimaryScreen.Bounds.Height;
 
            R = new Random();
            snowflakeCount = 0;
 
            snowflakes = new Bitmap[] { Properties.Resources.snowflake1, Properties.Resources.snowflake2,
                Properties.Resources.snowflake3, Properties.Resources.snowflake4 };
            tree = new Bitmap(Properties.Resources.tree1);
            rightDeer = new Bitmap(Properties.Resources.RightDeer);
            leftTop = new Bitmap(Properties.Resources.LeftTop);
            rightTop = new Bitmap(Properties.Resources.RightTop);
            cane = new Bitmap(Properties.Resources.cane);
            bulb = new Bitmap(Properties.Resources.bulb);
            snowMan = new Bitmap(Properties.Resources.BottomSnowMan);
            merry = new Bitmap(Properties.Resources.Merry);
            screen = ScreenCapture.Capture();
            buffer = new Bitmap(screenWidth, screenHeight);
        }
                
        private void Form1_Load(object sender, EventArgs e)
        {
            // 폼의 시작 위치를 생성자에서 설정하면 크기가 줄어드는 등 비정상적으로 동작한다.
            StartPosition = FormStartPosition.Manual;            
            Location = new Point(00);
            Size = new Size(screenWidth, screenHeight);
 
            button1.Location = new Point(screenWidth - button1.Size.Width - 10, screenHeight - button1.Size.Height - button2.Size.Height - 20);
            button2.Location = new Point(screenWidth - button2.Size.Width - 10, screenHeight - button2.Size.Height - 10);
 
            // Gets or sets a value indicating whether the form will receive key events before the event is passed to the control that has focus.
            // true if the form will receive all key events; false if the currently selected control on the form receives key events. The default is false.
            // 키가 눌렸을때 포커스를 갖고 있는 컨트롤보다 폼이 먼저 키 이벤트를 받을 수 있게 한다. 단축키 지정을 위해.
            KeyPreview = true;
 
            // 탭 스탑이 가능하면 포커스된 버튼에 파란색 테두리가 보인다.
            button1.TabStop = false;
            button2.TabStop = false;
 
            // 항상 위.
            TopMost = true;
 
            // 타이머 실행.
            timer1.Enabled = true;
            timer1.Interval = 100;
 
            drawBuffer();
 
            SoundPlayer p = new SoundPlayer();
            p.Stream = Properties.Resources.Song;
            p.Play();            
        }
 
        private void drawBuffer()
        {
            using (Graphics G = Graphics.FromImage(buffer))
            {
                G.DrawImage(screen, 00);
                G.DrawImage(bulb, screenWidth - rightDeer.Width - bulb.Width, 0);
                G.DrawImage(leftTop, 00);
                G.DrawImage(rightTop, screenWidth - rightTop.Width, 0);
                G.DrawImage(rightDeer, screenWidth - rightDeer.Width, (screenHeight - rightDeer.Height) / 2);
                G.DrawImage(cane, cane.Width / 4, (screenHeight - cane.Height) / 2);
                G.DrawImage(snowMan, 0, screenHeight - snowMan.Height);
                G.DrawImage(merry, screenWidth - merry.Width, screenHeight - merry.Height - 40);
                G.DrawImage(tree, (screenWidth - tree.Width) / 240);
            }
        }
 
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
 
                case Keys.Q:
                    Close();
                    break;
 
                case Keys.B:
                    TopMost = false;
                    System.Diagnostics.Process.Start("https://s-engineer.tistory.com/");
                    break;
 
                default:
                    break;
            }
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            Close();
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            TopMost = false;
            System.Diagnostics.Process.Start("https://s-engineer.tistory.com/");
        }
 
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            if (buffer != null)
            {
                e.Graphics.DrawImage(buffer, 00);
            }
        }
 
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // 전체 화면에 대해 더블 버퍼링을 하므로 배경화면을 다시 그리지 않도록 이 함수를 빈 함수로 재정의.
            //base.OnPaintBackground(e);
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            using (Graphics G = CreateGraphics())
            {
                G.DrawImage(snowflakes[R.Next(4)], R.Next(screenWidth), R.Next(screenHeight));
                snowflakeCount++;
            }
 
            // snowflake를 처음 100개 까지만 빨리 그리기
            if (snowflakeCount > 100 && timer1.Interval != 1000)
            {
                timer1.Interval = 1000;
            }
        }
    }
 
    public class ScreenCapture
    {
        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        private static extern IntPtr GetDC(IntPtr hWnd);
 
        [DllImport("user32.dll", ExactSpelling = true)]
        private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
 
        [DllImport("gdi32.dll", ExactSpelling = true)]
        private static extern IntPtr BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
 
        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        private static extern IntPtr GetDesktopWindow();
 
        public static Bitmap Capture()
        {
            int screenWidth = Screen.PrimaryScreen.Bounds.Width;
            int screenHeight = Screen.PrimaryScreen.Bounds.Height;
 
            Bitmap screenBmp = new Bitmap(screenWidth, screenHeight);
            Graphics g = Graphics.FromImage(screenBmp);
 
            IntPtr desktopDC = GetDC(GetDesktopWindow());
            IntPtr hDC = g.GetHdc();
 
            BitBlt(hDC, 00, screenWidth, screenHeight, desktopDC, 000x00CC0020);    //SRCCOPY (DWORD)0x00CC0020
 
            ReleaseDC(GetDesktopWindow(), desktopDC);
            g.ReleaseHdc(hDC);
            g.Dispose();
 
            return screenBmp;
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

 

실행하면 현재 화면이 캡쳐되어 리소스들과 함께 표시된다.

 

2021.12.23 - [C#] - C# Desktop(Screen) Capture - 스크린 캡쳐

 

반응형
Posted by J-sean
: