반응형

윈도우 사이즈 변경 시 적용되는 뷰포트 화면 비율 모드를 설정해 보자.

 

스프라이트를 하나 추가한다.

 

실행하면 스프라이트가 나타난다.

 

윈도우 사이즈를 변경하면 화면이 잘린다.

 

Project Settings... - Display - Window - Stretch - Mode를 viewport로 변경한다.

 

 

사이즈를 변경하면 뷰포트의 비율이 유지된 상태로 늘어나거나 줄어든다.

 

Aspect를 expand로 변경한다.

 

뷰포트의 비율이 유지되지 않은 상태로 늘어나거나 줄어든다.

 

반응형
Posted by J-sean
:
반응형

투명한 배경의 윈도우를 만들어 보자.

 

스프라이트를 추가하고 스크립트를 연결한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using Godot;
 
public partial class Control : Sprite2D
{
    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
    {
        GetViewport().TransparentBg = true;
    }
 
    public override void _Process(double delta)
    {
        RotationDegrees += 180.0f * (float)delta;
    }
}
 

 

위와 같은 코드를 작성한다.

 

Project Settings - Display - Window - Borderless / Transparent 옵션을 모두 체크한다.

 

실행하면 배경은 물론 타이틀바도 없는 윈도우에서 게임이 플레이된다.

 

반응형
Posted by J-sean
:
반응형

실행중인 모든 프로세스와 현재 포커스를 갖고 있는 프로세스를 조사하고 각 프로세스의 윈도우 사이즈를 구해 보자.

 

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
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.Diagnostics;
using System.Runtime.InteropServices;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string className, string windowName);
        // 이 예제에서는 쓰이지 않았지만 Findwindow()는 아래와 같이 사용하면 된다.
        // IntPtr hwnd = FindWindow(className, windowName);
        // windowName = proc.ProcessName;
        // className = proc.MainWindowTitle;
 
        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
 
        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();
 
        [DllImport("user32.dll")]
        private static extern int GetWindowRect(IntPtr hWnd, out Rectangle rect);
 
        [DllImport("dwmapi.dll")]
        private static extern int DwmGetWindowAttribute(IntPtr hWnd, int dwAttribute, out Rectangle pvAttribute, int cbAttribute);
        
        public Form1()
        {
            InitializeComponent();
 
            timer1.Interval = 5000// 5초마다 갱신
        }
        
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Process[] processes = Process.GetProcesses();            
            Rectangle rect;
            // GetWindowRect(), DwmGetWindowAttribute()에 의해 rect에는 아래와 같은 값이 들어간다.
            // rect.X = 좌상단 X 좌표
            // rect.Y = 좌상단 T 좌표
            // rect.Width = 우하단 X 좌표 (너비가 아니다)
            // rect.Height = 우하단 Y 좌표 (높이가 아니다)
            int rectangleSize = Marshal.SizeOf(typeof(Rectangle));
            int index;  // Process.GetProcesses()로 조사된 모든 프로세스 중 몇 번째 인지 나타낼 인덱스.
            int row = 0;    // 내용 표시 Y 위치
            string str;
 
            foreach (Process p in processes)
            { 
                // A process has a main window associated with it only if the process has a graphical interface. If the associated process
                // does not have a main window, the MainWindowHandle value is zero. The value is also zero for processes that have been hidden,
                // that is, processes that are not visible in the taskbar. This can be the case for processes that appear as icons in the
                // notification area, at the far right of the taskbar.
                // 테스크 바에 표시되는(보이는) 프로세스만 조사. 윈도우 핸들이 0(IntPtr.Zero)이 아닌 윈도우인데 그렇다고 다 보이는 건 아니다.
                if (p.MainWindowHandle != IntPtr.Zero)
                {
                    index = Array.IndexOf(processes, p); // 비효율적인 배열의 인덱스 가져오기. foreach()말고 for(;;)를 쓰는게 낫다.
                    DwmGetWindowAttribute(p.MainWindowHandle, 9out rect, rectangleSize);
                    // 9 = DWMWA_EXTENDED_FRAME_BOUNDS
                    str = string.Format("[{0}] {1}: ({2}, {3}, {4}, {5})", index, p.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
                    e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
                    row += 15;
                }
            }
            
            // 포커스를 갖고 있는 윈도우(Foreground window) 조사
            uint foregroundProcessID = 0;
            IntPtr foregroundHWnd = GetForegroundWindow(); // Get foreground window handle
            uint threadID = GetWindowThreadProcessId(foregroundHWnd, out foregroundProcessID); // Get PID from window handle
            Process foregroundProcess = Process.GetProcessById(Convert.ToInt32(foregroundProcessID)); // Get it as a C# obj.
 
            // 윈도우 사이즈 조사
            DwmGetWindowAttribute(foregroundHWnd, 9out rect, rectangleSize);
            // 9 = DWMWA_EXTENDED_FRAME_BOUNDS            
            str = string.Format("[Foreground] {0}: ({1}, {2}, {3}, {4})", foregroundProcess.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
            e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
            row += 30;
 
            // Windows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing.
            // The borders might look like this: 7, 0, 7, 7(left, top, right, bottom)
            // 윈도우 사이즈 조사 시 예전과 같이 GetWindowRect()를 사용하면 보통 7픽셀의 resizing을 위한 테두리가 포함된다.
            e.Graphics.DrawString("[Foreground window with invisible border]", Font, Brushes.Red, 0, row);
            row += 15;
            GetWindowRect(foregroundHWnd, out rect);
            str = string.Format("[Foreground] {0}: ({1}, {2}, {3}, {4})", foregroundProcess.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
            e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            Invalidate();
        }
    }
}
 

 

소스를 입력하고 실행한다.

 

인덱스를 확인하면 수백개의 프로세스가 실행중임을 알 수 있다.

 

GetWindowRect()로 윈도우 사이즈를 구하면 resizing을 위한 보이지 않는 테두리가 포함 되므로 눈에 보이는 정확한 사이즈는 DwmGetWindowAttribute()로 구하자.

 

반응형
Posted by J-sean
:
반응형

리눅스(우분투) 서버에 X Window(GUI)를 설치해 보자.


sudo apt update를 실행해서 package list를 업데이트한다.


업데이트가 완료되면 sudo apt upgrade를 실행해서 package를 upgrade/install/remove한다.


sudo apt install ubuntu-desktop-minimal 명령으로 X Window 설치를 진행한다.


sudo apt install ubuntu-desktop-minimal: 최소 설치

sudo apt install ubuntu-desktop: 전체 설치


1,695 MB의 디스크 공간이 필요하다. 설치는 꽤 오랫동안 진행된다.



설치가 완료되면 startx 명령어로 X Window를 실행한다.


Welcome! 이라고 한다.


키보드를 선택한다.


내 위치정보를 공개할지 선택한다.



간단한 설정이 완료되었다.


재부팅이 필요하다.


재부팅하면 바로 X Window가 실행된다. 로그인 하자.


X Window 화면이 나타난다.



부팅시 X Window가 자동 실행되지 않도록 하려면 아래 명령어를 입력한다.


sudo systemctl set-default multi-user


부팅시 다시 X Window가 자동 실행되게 하려면 아래 명령어를 입력한다.


sudo systemctl set-default graphical


직접 Run Level을 변경해 X Window 자동 실행 여부를 결정할 수 도 있다. 현재 default.target은 graphical.target을 가리키고 있다.


multi-user.target을 가리키도록 변경한다.



재부팅하면 X Window가 아닌 Console로 부팅된다.


startx를 실행하면 약간 다른 모양의 X Window가 실행된다.


Log Out 해 보자.


다시 콘솔 화면으로 돌아간다.


X Window로 부팅하려면 아래 명령어를 입력한다.

sudo ln -sf /lib/systemd/system/graphical.target /lib/sytemd/system/default.target


반응형
Posted by J-sean
:
반응형

Build a Windows dialog-based OpenCV program.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <Windows.h>
#include <gdiplus.h>
#include <opencv2/opencv.hpp>
#include "resource.h"
 
#pragma comment(lib, "gdiplus")
 
using namespace cv;
using namespace Gdiplus;
 
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);
HWND hDlgMain;
 
VideoCapture cap;
Mat frame;
RECT invalidateRect;


Prepare necessities.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    ULONG_PTR gpToken;
    GdiplusStartupInput gpsi;
 
    if (GdiplusStartup(&gpToken, &gpsi, NULL!= Ok) {
        MessageBox(NULL, TEXT("GDI+ start-up error."), TEXT("GDI+ Error"), MB_OK);
    }
 
    DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, MainDlgProc);
    
    GdiplusShutdown(gpToken);
 
    return 0;
}


Start GDI+ and create a modal dialog box from a dialog template resource.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool initCamera()
{
    cap.open(0);
    if (cap.isOpened()) {
        invalidateRect = { 00, cvRound(cap.get(CAP_PROP_FRAME_WIDTH)), cvRound(cap.get(CAP_PROP_FRAME_HEIGHT)) };
 
        return true;
    }
    else {
        MessageBox(NULL, TEXT("Camera open failed."), TEXT("Camera Error"), MB_OK);
 
        return false;
    }    
}


Initiate a camera and set the windows update region.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void OnPaint(HDC hdc)
{
    Graphics G(hdc);
 
    cap >> frame;
    if (frame.empty()) {
        TextOut(hdc, 300240"No frame to show"8);
 
        return;
    }
 
    if (IsDlgButtonChecked(hDlgMain, IDC_CHECK1) == BST_CHECKED) {
        cvtColor(frame, frame, COLOR_BGR2GRAY);
        Canny(frame, frame, 50100);
        cvtColor(frame, frame, COLOR_GRAY2BGRA);
    }
    else {
        cvtColor(frame, frame, COLOR_BGR2BGRA);
    }
 
    Bitmap bitmap(frame.size().width, frame.size().height, frame.step1(), PixelFormat32bppARGB, frame.data);
    G.DrawImage(&bitmap, 00, bitmap.GetWidth(), bitmap.GetHeight());
}


Process each frame and draw it. 


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
INT_PTR MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    static HANDLE hTimer;
 
    switch (iMessage) {
    case WM_INITDIALOG:
        hDlgMain = hDlg;
        if (initCamera()) {
            hTimer = (HANDLE)SetTimer(hDlg, 110NULL);
        }
        else {
            hTimer = NULL;
        }
 
        return TRUE;
 
    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
 
            return TRUE;
 
        case IDCANCEL:
            if (hTimer != NULL) {
                KillTimer(hDlg, 1);
            }
            EndDialog(hDlg, IDCANCEL);
 
            return TRUE;
        }
 
    case WM_PAINT:
        hdc = BeginPaint(hDlg, &ps);
        OnPaint(hdc);
        EndPaint(hDlg, &ps);
 
        return TRUE;
 
    case WM_TIMER:
        InvalidateRect(hDlg, &invalidateRect, FALSE);
        return 0;
    }
 
    return FALSE;
}


Create a timer and define the necessary variables and handle window messages.



Run the program.


Check 'Canny Edge Detection'.


반응형
Posted by J-sean
: