프로그램 구조

Java

package hello;


public class HelloWorld {
   public static void main(String[] args) {
      String name = "Java";

      // 매개변수를 확인
      if (args.length == 1)
         name = args[0];

      System.out.println("Hello, " + name + "!");
    }
}

C#

using System; 

namespace Hello {
   public class HelloWorld {
      public static void Main(string[] args) {
         string name = "C#";

         // 매개변수를 확인
         if (args.Length == 1)
            name = args[0];

         Console.WriteLine("Hello, " + name + "!");
      }
   }
}

Java 소스 파일의 확장자는 *.java이고, C#은 *.cs이다.

Java는 클래스마다 별도의 파일을 작성해야 하고 클래스명과 파일명이 일치해야 하지만, C#에서는 하나 이상의 최상위 클래스를 작성할 수 있고 파일명에 대한 제한도 없다.

Java

package harding.compsci.graphics;










// 단일 클래스를 임포트
import harding.compsci.graphics.Rectangle;
// 여러 클래스를 임포트
import harding.compsci.graphics.*; 

C#

namespace Harding.Compsci.Graphics {
  ...
}
또는
namespace Harding {
  namespace Compsci {
    namespace Graphics {
      ...
    }
  }
}
// 단일 클래스를 임포트
using Rectangle = Harding.CompSci.Graphics.Rectangle;
// 여러 클래스를 임포트
using Harding.Compsci.Graphics;

Java는 소스 코드의 첫 줄에 package를 선언하지만, C#에서는 namespace 키워드를 사용해서 블록으로 묶는다. C#에서는 하나의 소스 코드 파일에 여러 개의 네임스페이스를 포함시는 것도 가능하다.

Java의 import 키워드 대신, C#에서는 using 키워드를 사용한다. using 키워드를 namespace 블록 내부에 사용할 수도 있다. using 키워드를 사용해서 별칭을 지정할 수도 있다.

주석

Java

// 한 줄 주석
/* 여러 줄
    주석  */
/** 자바독 문서화 주석 */

C#

// 한 줄 주석
/* 여러 줄
    주석  */
/// 한 줄 XML 주석
/** 여러 줄 XML 주석 */

자료형

Java

원시 자료형
boolean
byte
char
short, int, long
float, double


참조 자료형
Object   (다른 모든 클래스들의 부모 클래스)
String
arrays, classes, interfaces

형 변환
// 정수를 문자열로 
int x = 123; 
String y = Integer.toString(x);  // y is "123"
// 문자열을 정수로
y = "456"; 
x = Integer.parseInt(y);   // x is 456
// 부동소수를 정수로
double z = 3.5; 
x = (int) z;   // x는 3  (소수부는 잘림)

C#

값 타입
bool
byte, sbyte
char
short, ushort, int, uint, long, ulong
float, double, decimal
structures, enumerations

참조 자료형
object    ( 다른 모든 클래스들의 부모 클래스)
string
arrays, classes, interfaces, delegates

형 변환
// 정수를 문자열로 
int x = 123; 
String y = x.ToString();  // y is "123"
// 문자열을 정수로
y = "456"; 
x = int.Parse(y);   // 또는 x = Convert.ToInt32(y);
// 부동소수를 정수로
double z = 3.5; 
x = (int) z;   // x는 3  (소수부는 잘림)

Java에서 지원되는 원시 자료형과 더불어, C#에서는 부호 없는(unsigned) 자료형과 128비트 부동 소수 형식(decimal)을 추가로 지원한다.

Java에서는 원시 자료형이 존재하고 각각의 래퍼 클래스가 존재하지만, C#에서 모든 원시 자료형은 System 네임스페이스의 객체이며 각각 별칭이 존재한다.

Java의 boolean은 C#에서 bool이다.

상수

Java

// 생성자에서 초기화 될 수 있음
final double PI = 3.14;

C#

const double PI = 3.14;

// const 또는 변수에 지정할 수 있음. 생성자에서 초기화 될 수 있음.
readonly int MAX_HEIGHT = 9;

Java에서는 final 키워드를, C#에서는 const와 readonly 키워드를 사용한다.

const 키워드를 사용하면 런타임시에 값을 변경할 수 없지만, readonly 키워드를 지정하면 런타임시에 단 한번 값을 지정할 수 있다.

열거형

Java

enum Action {Start, Stop, Rewind, Forward};
// 특수한 형태의 클래스이다. 
enum Status {
  Flunk(50), Pass(70), Excel(90);
  private final int value;
  Status(int value) { this.value = value; }
  public int value() { return value; } 
};
Action a = Action.Stop;
if (a != Action.Start)
  System.out.println(a);      // Prints "Stop"
Status s = Status.Pass;
System.out.println(s.value());      // Prints "70"

C#

enum Action {Start, Stop, Rewind, Forward};
enum Status {Flunk = 50, Pass = 70, Excel = 90};






Action a = Action.Stop;
if (a != Action.Start)
  Console.WriteLine(a);             // Prints "Stop"
Status s = Status.Pass;
Console.WriteLine((int) s);       // Prints "70"

Java 1.5 이상에서 enum을 지원한다.

C# 3.0 이상에서는 확장메서드를 통해서 enum 타입에 메서드를 정의할 수 있다.

연산자

Java

비교
==  <  >  <=  >=  !=

산술
+  -  *  /
%  (mod)
/   (integer division if both operands are ints)
Math.Pow(x, y)

할당
=  +=  -=  *=  /=   %=   &=  |=  ^=  <<=  >>=  >>>=  ++  --

비트
&  |  ^   ~  <<  >>  >>>

논리
&&  ||  &  |   ^   !

문자열 결합
+

C#

비교
==  <  >  <=  >=  !=

산술
+  -  *  /
%  (mod)
/   (integer division if both operands are ints)
Math.Pow(x, y)

할당
=  +=  -=  *=  /=   %=  &=  |=  ^=  <<=  >>=  ++  --


비트
&  |  ^   ~  <<  >>

논리
&&  ||  &  |   ^   !

문자열 결합
+

연산자 오버로딩
public static ComplexNumber operator+(ComplexNumber a, ComplexNumber b) { ...

Java의 >>> 연산자는 C#에서 사용할 수 없다. 이는 부호없는 자료형이 지원되기 때문이다.

C#의 checked, unchecked 키워드를 사용해서 오버플로우를 검사할 수 있다.

C#에서는 연산자 오버로딩을 위해 operator 키워드를 지원한다.

연산자 오버로딩은 static 메서드로 선언하고 메서드 이름 대신에 operator 키워드와 연산자 심볼을 붙인다.

조건문

Java

greeting = age < 20 ? "What's up?" : "Hello";

if (x < y) 
  System.out.println("greater");

if (x != 100) {    
  x *= 5; 
  y *= 2; 
} 
else 
  z *= 6;

int selection = 2;
switch (selection) { // byte, short, int, char, enum
  case 1: x++;   // break가 없으면 다음으로 넘어간다
  case 2: y++;   break; 
  case 3: z++;   break; 
  default: other++;
}

C#

greeting = age < 20 ? "What's up?" : "Hello";

if (x < y)  
  Console.WriteLine("greater");

if (x != 100) {    
  x *= 5; 
  y *= 2; 
} 
else 
  z *= 6;

string color = "red";
switch (color) {    //자료형 제한이 없다.
  case "red":    r++;    break;  // break 꼭 필요
  case "blue":   b++;   break; 
  case "green": g++;   break; 
  default: other++;     break; 
}

Java 7이후부터 switch문에 문자열을 사용할 수 있다.

Java와 달리 C#에서는 case문 다음에 반드시 break문이 존재해야 한다.

반복문

Java

while (i < 10) 
  i++;

for (i = 2; i <= 10; i += 2) 
  System.out.println(i);

do 
  i++; 
while (i < 10);

for (int i : numArray)  // foreach construct  
  sum += i;

import java.util.ArrayList;
ArrayList<Object> list = new ArrayList<Object>();
list.add(10); 
list.add("Bisons");
list.add(2.3);    
for (Object o : list)
  System.out.println(o);

C#

while (i < 10) 
  i++;

for (i = 2; i <= 10; i += 2) 
  Console.WriteLine(i);

do 
  i++; 
while (i < 10);

foreach (int i in numArray)  
  sum += i;
 
using System.Collections;
ArrayList list = new ArrayList();
list.Add(10);
list.Add("Bisons");
list.Add(2.3);
foreach (Object o in list)
  Console.WriteLine(o);

배열

Java

int nums[] = {1, 2, 3};   
     또는   int[] nums = {1, 2, 3};

for (int i = 0; i < nums.length; i++)
  System.out.println(nums[i]);

String names[] = new String[5];
names[0] = "David";

float twoD[][] = new float[rows][cols];
twoD[2][0] = 4.5;

int[][] jagged = new int[5][]; 
jagged[0] = new int[5]; 
jagged[1] = new int[2]; 
jagged[2] = new int[3]; 
jagged[0][4] = 5;

C#

int[] nums = {1, 2, 3};


for (int i = 0; i < nums.Length; i++)
  Console.WriteLine(nums[i]);

string[] names = new string[5];
names[0] = "David";

float[,] twoD = new float[rows, cols];
twoD[2,0] = 4.5f;

int[][] jagged = new int[3][] {
    new int[5], new int[2], new int[3] }; 
jagged[0][4] = 5;

Java와 달리 C#에서는 배열을 나타내는 대괄호 []는 반드시 자료형 다음에 와야 한다.

배열의 초기화 시에도, Java와 달리 C#에서는 배열의 크기와 초기값의 수가 일치해야 한다.

C#에서는 Jagged 배열 외에 다차원 배열을 추가로 지원한다.

메서드

Java

// 값을 반환
int Add(int x, int y) { 
   return x + y; 
}

int sum = Add(2, 3);
// 결과값을 반환하지 않음
void PrintSum(int x, int y) { 
   System.out.println(x + y); 
}
PrintSum(2, 3); 

// 값에 의한 전달
void TestFunc(int x, Point p) {
   x++; 
   p.x++;       // 객체 값 변경
   p = null;    // 객체 참조를 제거 
}
class Point { 
   public int x, y; 
}
Point p = new Point(); 
p.x = 2; 
int a = 1; 
TestFunc(a, p);
System.out.println(a + " " + p.x + " " + (p == null) );  // 1 3 false 




// 임의의 갯수의 매개변수
int Sum(int ... nums) {
  int sum = 0;
  for (int i : nums)
    sum += i;
  return sum;
}
int total = Sum(4, 3, 2, 1);   // returns 10

C#

// 값을 반환
int Add(int x, int y) { 
   return x + y; 
}

int sum = Add(2, 3);
// 결과값을 반환하지 않음
void PrintSum(int x, int y) { 
   Console.WriteLine(x + y); 
}
PrintSum(2, 3); 

// 값에 의한 전달, ref, out
void TestFunc(int x, ref int y, out int z, Point p1, ref Point p2) { 
   x++;  y++;  z = 5; 
   p1.x++;       // 객체 값 변경     
   p1 = null;    // 객체 참조를 제거 
   p2 = null;   // 객체 참조를 제거 
}
class Point { 
   public int x, y; 
}
Point p1 = new Point(); 
Point p2 = new Point(); 
p1.x = 2; 
int a = 1, b = 1, c;   // out은 초기화 필요 없음
TestFunc(a, ref b, out c, p1, ref p2); 
Console.WriteLine("{0} {1} {2} {3} {4}", 
   a, b, c, p1.x, p2 == null);   // 1 2 5 3 True

// 임의의 갯수의 매개변수
int Sum(params int[] nums) {
  int sum = 0;
  foreach (int i in nums)
    sum += i;
  return sum;
}
int total = Sum(4, 3, 2, 1);   // returns 10

C#에서는 값 형식의 데이터를 참조 형식으로 매개변수를 전달하기 위해서 ref, out 키워드를 지원한다.

ref의 경우 사용하기 전에 반드시 초기화 되어 있어야 하고, out의 경우 메서드 내에서 사용하기 전에 값을 할당해야 한다.

임의의 갯수의 매개변수를 전달 받으려는 경우, Java는 ...을, C#은 params 키워드를 사용한다.

문자열

Java

// 결합
String school = "Harding "; 
school = school + "University";   // school is "Harding University"

// 비교
String mascot = "Bisons"; 
if (mascot == "Bisons")    // 틀려!
if (mascot.equals("Bisons"))   // true
if (mascot.equalsIgnoreCase("BISONS"))   // true
if (mascot.compareTo("Bisons") == 0)   // true
System.out.println(mascot.substring(2, 5));   // Prints "son"

// 날짜
java.util.Calendar c 
  = new java.util.GregorianCalendar(1973, 10, 12);
String s 
  = String.format("My birthday: %1$tb %1$te, %1$tY", c);

// 조작가능한 문자열 
StringBuffer buffer = new StringBuffer("two "); 
buffer.append("three "); 
buffer.insert(0, "one "); 
buffer.replace(4, 7, "TWO"); 
System.out.println(buffer);     // Prints "one TWO three"

String path = "\\\\FileShare\\Directory\\file.txt";

C#

// 결합
string school = "Harding "; 
school = school + "University";   // school is "Harding University"

// 비교
string mascot = "Bisons"; 
if (mascot == "Bisons")    // true
if (mascot.Equals("Bisons"))   // true
if (mascot.ToUpper().Equals("BISONS"))   // true
if (mascot.CompareTo("Bisons") == 0)    // true
Console.WriteLine(mascot.Substring(2, 3));    // Prints "son"

// 날짜
DateTime dt 
  = new DateTime(1973, 10, 12);
string s 
  = "My birthday: " + dt.ToString("MMM dd, yyyy");


// 조작가능한 문자열 
System.Text.StringBuilder buffer = new System.Text.StringBuilder("two "); 
buffer.Append("three "); 
buffer.Insert(0, "one "); 
buffer.Replace("two", "TWO"); 
Console.WriteLine(buffer);     // Prints "one TWO three"
string path = @"\\FileShare\Directory\file.txt";

문자열 비교시에, Java는 equals() 메서드를 사용하지만, C#에서는 == 또는 != 연산자를 사용할 수 있다.

C#에서는 변수에 할당되는 문자열 앞에 @을 붙여서 이스케잎 문자를 효율적으로 처리할 수 있다.

예외처리

Java

// 메서드에서 예외를 던질 수 있도록 선언되어야 함
Exception ex 
  = new Exception("Something is really wrong."); 
throw ex;  

try {
  y = 0; 
  x = 10 / y;
} catch (Exception ex) {
  System.out.println(ex.getMessage()); 
} finally {
  // Code that always gets executed
}

C#

Exception up 
  = new Exception("Something is really wrong."); 
throw up;  // ha ha

try {
  y = 0; 
  x = 10 / y;
} catch (Exception ex) { // 매개변수가 없어도 됨
  Console.WriteLine(ex.Message); 
} finally {
  // Code that always gets executed
}

C#의 catch 블록에서 매개변수를 생략할 수도 있다.

C#에서는 throws 키워드가 없다.

클래스 / 인터페이스

Java

접근 키워드
public
private
protected
static



// 상속
class FootballGame extends Competition {
  ...
}

// 인터페이스
interface IAlarmClock {
  ...
}

// 인터페이스의 상속
interface IAlarmClock extends IClock {
  ...
}

// 인터페이스 구현
class WristWatch implements IAlarmClock, ITimer {
   ...
}

C#

접근 키워드
public
private
internal
protected
protected internal
static

// 상속
class FootballGame : Competition {
  ...
}

// 인터페이스
interface IAlarmClock {
  ...
}

// 인터페이스의 상속
interface IAlarmClock : IClock {
  ...
}

// 인터페이스 구현
class WristWatch : IAlarmClock, ITimer {
   ...
}

Java의 기본 접근 제한자는 동일 패키지 내에서 접근 가능인 반면, C#에서는 private이다.

C#의 internal 키워드는 현재 어셈블리 내에서만 접근 가능하도록 지정하는 것이며, 어셈블리는 Java의 Jar파일과 유사한 개념이다.

Java에서 클래스가 더이상 상속 될 수 없도록 지정하는 final 키워드 대신, C#에서는 sealed 키워드를 사용한다.

Java에서 상속과 구현을 나타내는 키워드인 extends와 implements 대신, C#에서는 :을 사용한다.

Java의 super 키워드 대신, C#에서는 base 키워드를 사용한다.

Java와 달리, C#에서는 오버라이드 될 메서드에는 virtual 키워드를 오버라이드 하는 메서드에는 override 키워드를 사용한다.

C#에서는 인덱서를 지원하므로 이를 이용하면 클래스나 구조체를 배열처럼 다룰 수 있다.

객체

Java

SuperHero hero = new SuperHero();
hero.setName("SpamMan"); 
hero.setPowerLevel(3); 

hero.Defend("Laura Jones");
SuperHero.Rest();  // 정적 메서드 호출
SuperHero hero2 = hero;   // 동일한 객체를 참조

hero2.setName("WormWoman"); 
System.out.println(hero.getName()); 

hero = null;   // Free the object
if (hero == null)
  hero = new SuperHero();
Object obj = new SuperHero(); 
System.out.println("object's type: " + obj.getClass().toString()); 
if (obj instanceof SuperHero) 
  System.out.println("Is a SuperHero object.");

C#

SuperHero hero = new SuperHero(); 
hero.Name = "SpamMan"; 
hero.PowerLevel = 3;

hero.Defend("Laura Jones");
SuperHero.Rest();   // 정적 메서드 호출
SuperHero hero2 = hero;   // 동일한 객체를 참조
 
hero2.Name = "WormWoman"; 
Console.WriteLine(hero.Name);  

hero = null ;   // Free the object
if (hero == null)
  hero = new SuperHero();
Object obj = new SuperHero(); 
Console.WriteLine("object's type: " + obj.GetType().ToString()); 
if (obj is SuperHero) 
  Console.WriteLine("Is a SuperHero object.");

생성자 / 파괴자

Java

class SuperHero {
  private int mPowerLevel;

  public SuperHero() {
    mPowerLevel = 0;
  }

  public SuperHero(int powerLevel) {
    this.mPowerLevel= powerLevel;
  }

  // 파괴자는 없음
  protected void finalize() throws Throwable { 
    super.finalize();   // 항상 부모 요소를 호출
  }
}

C#

class SuperHero {
  private int mPowerLevel;

  public SuperHero() {
     mPowerLevel = 0;
  }

  public SuperHero(int powerLevel) {
    this.mPowerLevel= powerLevel; 
  }

  ~SuperHero() {
    // Destructor code to free unmanaged resources.
    // Implicitly creates a Finalize method.
  }
}

Java에서는 finalize() 메서드를 사용해서 가비지 컬렉터에 의해 인스턴스가 정리되기 직전에 실행될 메서드를 지정하는 반면, C#에서는 매개변수 없는 생성자와 유사한 형식으로 지정하며 이름 앞에 물결 표시(~)를 붙인다.

속성

Java

private int mSize;

public int getSize() { return mSize; } 
public void setSize(int value) {
  if (value < 0) 
    mSize = 0; 
  else 
    mSize = value; 
}


int s = shoe.getSize();
shoe.setSize(s+1);

C#

private int mSize;

public int Size { 
  get { return mSize; } 
  set { 
    if (value < 0) 
      mSize = 0; 
    else 
      mSize = value; 
  } 
}

shoe.Size++;

C#에서는 private 멤버 변수의 getter와 setter 메서드를 처리하는 get, set 키워드를 지원한다.

구조체

Java

x

C#

x

x

프로그램 구조

Java

 

C#

struct StudentRecord {
  public string name;
  public float gpa;

  public StudentRecord(string name, float gpa) {
    this.name = name;
    this.gpa = gpa;
  }
}

StudentRecord stu = new StudentRecord("Bob", 3.5f);
StudentRecord stu2 = stu;  

stu2.name = "Sue";
Console.WriteLine(stu.name);    // Prints "Bob"
Console.WriteLine(stu2.name);   // Prints "Sue"

C#에서는 클래스와 유사한 구조체라는 자료형을 지원한다. 단, 구조체는 상속이 불가능하고, 참조형 데이터가 아니다.

이벤트

Java

 

C#

window.ClickedEvent += MyEventHandler;

Java의 경우 이벤트를 수신할 클래스에서 Listener를 구현한 후 이벤트를 발생시키는 객체에 등록(register)하지만, C#에서 이벤트는 이벤트를 발생시키는 객체의 멤버이므로 이벤트 핸들러 메서드를 추가하기만 하면 된다.

C#에서는 이벤트 핸들러 메서드를 위해 delegate 키워드를 제공한다. 딜리게이트는 함수 포인터와 유사한 개념이다.

콘솔 입출력

Java

java.io.DataInput in 
= new java.io.DataInputStream(System.in);
System.out.print("What is your name? ");
String name = in.readLine();

System.out.print("How old are you? ");
int age = Integer.parseInt(in.readLine());
System.out.println(name + " is " + age + " years old.");
int c = System.in.read();   // Read single char
System.out.println(c);      // Prints 65 if user enters "A"

// The studio costs $499.00 for 3 months.
System.out.printf("The %s costs $%.2f for %d months.%n",

 

"studio", 499.0, 3); // Today is 06/25/04 System.out.printf("Today is %tD\n", new java.util.Date());

C#

Console.Write("What's your name? ");
string name = Console.ReadLine();



Console.Write("How old are you? ");
int age = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("{0} is {1} years old.", name, age);
// 또는
Console.WriteLine(name + " is " + age + " years old.");

 

int c = Console.Read(); // Read single char Console.WriteLine(c); // Prints 65 if user enters "A" // The studio costs $499.00 for 3 months. Console.WriteLine("The {0} costs {1:C} for {2} months.\n", 

"studio", 499.0, 3); // Today is 06/25/2004 Console.WriteLine("Today is"+ DateTime.Now.ToShortDateString());

파일 입출력

Java

import java.io.*;

// Character stream writing
FileWriter writer 
  = new FileWriter("c:\\myfile.txt");
writer.write("Out to file.\n");
writer.close();

// Character stream reading
FileReader reader 
  = new FileReader("c:\\myfile.txt");
BufferedReader br = new BufferedReader(reader);
String line = br.readLine(); 
while (line != null) {
  System.out.println(line); 
  line = br.readLine(); 
} 
reader.close();

// Binary stream writing
FileOutputStream out 
  = new FileOutputStream("c:\\myfile.dat");
out.write("Text data".getBytes());
out.write(123);
out.close();

// Binary stream reading
FileInputStream in 
  = new FileInputStream("c:\\myfile.dat");
byte buff[] = new byte[9];
in.read(buff, 0, 9);   // Read first 9 bytes into buff
String s = new String(buff);
int num = in.read();   // Next is 123
in.close();

C#

using System.IO;

// Character stream writing
StreamWriter writer 
  = File.CreateText("c:\\myfile.txt"); 
writer.WriteLine("Out to file."); 
writer.Close();

// Character stream reading
StreamReader reader 
  = File.OpenText("c:\\myfile.txt"); 
string line = reader.ReadLine(); 
while (line != null) {
  Console.WriteLine(line); 
  line = reader.ReadLine(); 
} 
reader.Close();



// Binary stream writing
BinaryWriter out 
  = new BinaryWriter(File.OpenWrite("c:\\myfile.dat")); 
out.Write("Text data"); 
out.Write(123); 
out.Close();

// Binary stream reading
BinaryReader in 
  = new BinaryReader(File.OpenRead("c:\\myfile.dat")); 
string s = in.ReadString(); 
int num = in.ReadInt32(); 
in.Close();

C#에는 이 외에 인덱서, unsafe, fixed 등이 더 있음.


출처: http://www.elex.pe.kr/entry/Java-cf-C-Sharp [Elex]

OOPreport.txt

 

OOP (Object-oriented programming,객체지향프로그래밍)

  

프로그래밍 방법론으로 클래스,자료 추상화,상속,다형성,캡슐화등을 이용하여 프현실세계를 시스템을 독립적 객체들의 집합으로 모델링 하는것이다. 다른 방법론들 또한 현실세계를 모델링 하므로 OOP의 고유특성은 아니나 사물과 그 행위을 하나로 묶고 객체간의 메시지를 기본 모형으로 하기때문에 각 객체가 종속 될 필요가 없고 객체지향프로그래밍의 장점으로 나타난다. 이 장점 때문인지 현재 프로그래밍 방법론 중 가장 많이 쓰이고 있다.

객체지향프로그래밍의 장점으로는 시스템의 복잡성을 낮추며 코드의 재사용성 증가, 유지보수 감소등을 들수있다.

 

 

Objcet, 객체

현실세계의 존재하는 모든 것을 말하며 예를 들어 사람,동물,교실 처럼 실체하는 것부터 거래,계좌,수학 같은 개념적인 것을 모두 포함한다. 객체는 식별성, 상태(state), 행위(behavior)의 특성을 같는다. 현실의 객체는 무한에 가까운 특성을 가지고 있기때문에 이를 모델링 하기 위해서는 시스템에 필요한 요소만을 분류/집합 해야만 한다. 

객체지향프로그래밍이라는 이름에서 알 수 있듯이 OOP에서 중요한 개념이다.

 

Class, 클래스

 

모든 객체는 클래스를 통해 정의 될 수있다. 클래스는 여러객체들의 공통적인 상태와 행동을 가지고 있는데 이 과정을 추상화라고 한다. 클래스가 정의 된 후 객체가 정의되는데 이렇게 한 클래스에 속한 각가의 객체를 그 클래스의 인스턴스(instance)라고 한며, 그 객체들의 유형이 되는 클래스를 객체의 타입(Object Type)이라고 한다.

 

 

Abstraction, 추상화

현실세계의 객체의 일반적인 특징을 표현하기에는 너무많은 특징을 가지고 있다. 때문에 모델링하고자 하는 시스템에 필요한 정보를 집중, 분류하며 상세내역을 없애가는 과정을 추상화라고 한다. 시스템에 따라 필요정보가 다르기때문에 시스템에 의존적이게 된다.

 

Generalization, 일반화 / Inheritance, 상속

'남자와 여자는 사람이고 사람과 강아지는 동물이다' 처럼 클래스의 공통 된 특징을 추출하여 상위 클래스로 추상화 되는데 일반화란 이처럼 추상적으로 상위 클래스로 향함을 말한다. 

상속이란 일종의 일반화이다.

상속은 일반화한 상위클래스를 이용하여 공통 된 특징이외 고유의 특징을 추가하여 하위 클래스를 만들게되면 이 둘의 관계를 상속관계라고 한다.

상속을 통하여 기존의 클래스로부터 추가적 특성을 추가하는 것 만으로 하위클래스를 정의 할 수있기때문에 반복을 막아주고 재사용성이 늘어나게된다.

Java에서 extends 키워드를 통한 상속을 지원하고 상위 클래스를 공유하는 의미를 지닌다.

 

Specialization, 구체화

일반화와는 반대로 상속을 통해 클래스의 추상 수준을 낮추어 나가는 과정을 구체화라 한다. 

일반화와 구체화는 클래스간의 is-a 관계를 나타낸다.

 

Realization

추상화 과정을 거쳐 만들어진 클래스를 하나의 객체로 만드는 것을 말하다.

이때 만들어진 객체를 클래스의 인스턴스라고 한다.

예를 들면 사람이라는 클래스로부터 홍길동이라는 인스턴스가 나타난것이다.

Java에서 완전한 추상클래스를 지원하기 위해 interface를 제공한다. 

implements로 사용 할 수있으며 상속과 마찬가지고 is-a관계를 갖고 있지만 상속은 공유의 의미를 가지고 인터페이스는 구현의 의미를 가진다.


Association (소유)

객체간의 참조관계를 나타낸다. 

예를 들면 자동차의 구성으로 사람이라는 객체의 구성으로 팔,다리,머리들이 있고 머리는 눈,코,입을 가지고있듯이 객체간의 has-a 관계를 나타낸다.

 

Dependency, 종속성 (사용)

A라는 클래스가 B라는 클래스 또는 인터페이스를 사용할때 마다 A는 B에 의존하게 된다. 이때 A가 B에 종속되어있다고 할 수있으며 이는 종속에는 방향성이 있기에 A가 B에 종속된다해소 B가A에 종속되었다고 볼수는 없다.

A는 B 없이는 사용 될 수없고 이때문에 재사용을 어렵게 할 수있기때문에 개발에 부정적인 영향을 끼칠 수 있다.

이에 관련 Dependency Inversion Principle(DIP, 의존성 역전 원칙)

"상위 레벨의 모듈은 하위 레벨들에 의존해선 안되며, 모든 것들은 추상에 의존해야 한다"는 중요개념이 있다.


Polymorphism, 다형성

객체지향 개념에서의 다형성이란 '여러 가지 형태를 가질 수 있는 능력'을 의미하며 구현과정에서는 같은 상위클래스를 상속받아 동일한 메소드를 가지고있는 클래스들을 공통으로 상속받고있는 클래스 타입으로 참조하여 실제 구현내용은 다르지만 같은 타입으로 참조하기때문에 코드의 유지보수와 확장성에 유리하게 작용한다.



Encapuslation / 절차은닉 / 정보은닉

객체지향에서 캡슐화는 상태와 행위을 하나로 묶고 정보의 처리와 접근을 모두 클래스 내부에서 하도록 하는것이다. 

외부와의 상호작용은 메소드 호출로만 이루어지기때문에 외부로터 필드로 무분별한 접근을 막을 수있고 내부 내용의 변경이 외부에 영향을 끼치지않는다. 이로인하여 유지보수와 재상용성이 늘어나고 필드의 값이 손상 될 가능성또한 낮출수있다.

Access Modifier(접근 제한자)

정보를 은닉하기위해 프로그래밍언어에서는 Access Modifier(접근제한자)를 지원한다.

Java

public : 어디서나 접근가능

protected : 같은 패키지, 상속받은 클래스에서 접근가능

default : 같은 패키지에서만 접근가능

private : 외부접근 불가능




Transform.Rotate



Transform.Rorate(Vector3 eulerAngles)

ex)

void Update(){

this.Transform.Rotate(new vector3(0,10,0));

}

//y축을 10도씩 회전한다. 


Transform.Rorate(Vector3 eulerAngles,Space relativeTo)

ex)

void Update(){

this.Transform.Rotate(new vector3(0,10,0),Space.World); //Space.Self

}

//Space.World 또는 Space.Self 인자를 통하여 

//월드축을 기준으로 할지 로컬축을 기준으로 할지 정할수있다.

//만약 오브젝트가 회전한 상태일지라도 위와 같은 코드에서는 월드의 y축을

//기준으로 회전하는것을 볼 수 있다.


※덧셈과 곱셈의 결합법칙 및 덧셈의 교환법칙을 만족시키지만 곱셈의 교환법칙은 성립하지 않는다.

※3D 그래픽에서 회전행렬 대신 사용시 짐벌락(gimbal lock)현상을 을 피할수있다.

※행렬연산에 비해 빠르다.



1. 사원수(Quaternion : 쿼터니언)란?


- 3차원 그래픽에서 회전을 표현할 때, 행렬 대신 사용하는 수학적 개념으로 4개의 값으로 이루어진 복소수(Complex Number) 체계이다.

아래 글에선 사원수와 쿼터니언을 번갈아가며 썼다.


(잠깐! 복소수란 현재 교육과정 중 가장 큰 범위의 수로 실수부와 허수부의 합으로 구성된 수이다.)


그렇다면, 사원수를 사용하는 이유는 무엇일까?


 



- 사원수는 행렬에 비해 연산 속도가 빠르고, 차지하는 메모리의 양도 적으며, 결과의 질에 있어 오류가 날 확률이 적다.


3개의 축에 대한 회전 연산을 동시에 적용하는 경우에 행렬을 사용하면 한 축이 소실되는 김벌락 현상이 발행할 수 있는데, 사원수를 사용하면 이 현상을 막을 수 있다. (미리 말해두지만, 사실 이것도 완벽하기 막지는 못한다.)



2. 사원수의 정의


- 사원수는 4차원 복소수 공간(Complex Space)의 벡터로서 다음과 같이 나타낸다.





- 사원수를 q = s + v 형태로 쓰기도 하는데, 여기서 s 는 q의 w 성분에 해당하는 스칼라(Scalar) 값이고, v는 q의 x, y, z 성분에 해당하는 벡터(Vector) 부분이다.





3. 사원수의 특징


- 사원수의 곱은 일반적인 분배법칙을 따르며 허수 성분인 i, j, k는 다음과 같은 특징을 갖는다.



(필자의 생각)

여기서 i, j, k 는 각각 x, y, z축에 대비된다고 할 수 있다. 정확히 그 축을 말하는 것이 아니라 어떠한 물체의 3축이라는 것이다. 따라서 서로 직교 하므로 ij와 ji는 교환법칙이 성립하지 않고, 역수 관계인 것이다.

또한, 서로 외적하면 다른 축을 가리킨다. 때문에 각각의 축에 대비된다고 할 수 있다.











- 사원수는 곱셈의 교환법칙이 성립하지 않는다.



위와 같은 두 사원수 q1,q2가 있을 때, 두 사원수의 곱q1q2는 다음과 같다. 




사원수를 스칼라, 벡터 형태로 표기할 때, 


 이렇게 표현할 수 있고, 두 사원수의 곱은 다음과 같다.




이는 앞에서 나온 q1,q2의 곱의 부호를 제외하고 곱했을 때 나온 값과 같다.




- 사원수는 켤레(Conjugate)를 갖는다.




- 사원수의 역수  



그리고 아래와 같은 특징을 갖는다.




- 단위 쿼터니언을 갖는다.


q = [1, (0, 0, 0)]




단위 쿼터니언은 3D 공간에서 오일러, Axis 대신 방향을 표현한다.


쿼터니언으로 방향을 표현하려면 쿼터니언을 행렬로 변환하거나, 행렬을 쿼터니언으로 변환하는 방법이 필요하다.



3. 사원수의 회전

- 축 A에 대한 각도 Θ 만큼의 회전을 사원수로 나타내면,이다.


(이것에 대한 증명 과정은 추후 업로드 할까말까...ㅠㅜ)


이 사원수로 점 P를 회전하려면 qPq-1을 하면된다.


최종적으로 얻어진 사원수를 행렬로 변환하면, 아래와 같다.






4. 사원수의 보간


보간(interpolation)이란 처음과 끝의 값을 가지고 중간에 잇는 값을 계산해 내는 것이다.

물체의 애니메이션을 수행할 때, 보간을 통해 계산된 키프레임 사이의 중간 방향을 생성한다.


가장 간단한 보간은 선형보간(linear interpolation)으로 두 개의 값을 점으로 생각하고 두 개의 점을 이어주는 직선의 방정식으로부터 값을 얻어내는 방법이다.

두 사원수 q1,q2에 대해, 선형 보간된 사원수 q(t)는 다음과 같다.



이런 사원수는 정규화 해줘야 한다. 이 함수 q(t)는 q1과 q2사이의 호를 따라간다.



그림은 2차원 단면이나, 실제로는 4차원 단위 초구면 상의 경로를 따라간다.


이러한 선형 보간은 간단하고, 효과적이나 호를 일정한 비율로 추적하지 않는다는 문제가 있다.


여기에서 구면 선형보간(spherical linear interpolation : slerp)이 나타났다.


일단 유도과정은 생략하고 보면 다음과 같다.









C#에 DataGrid를 다루다 보면 cell BeginEdit(셀 에디트를 위해)를 호출 하게 되는데 , 이때 영어 같은 경우는 합성 문자가 아니기 때문에 상관이 없지만, 한글 같은 경우는 합성 문자이기때문에 첫번째 타이핑을 할때 IME_Composition 인 상태의 커서를 만들어야 한글 입력이 제대로 된다.

하지만 DataGrid(WPF)의 경우에는 딱히 지원이 없어 보인다. 또 나같은 경우는 한글키 입력 일경우에는  KEY_DOWN 메세지 자체를 프로그램에서 캐치 하지 못했다. 해서 전역 후킹을 통해서 이문제를 해결했다.  

 @소스코드

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
#region 전역 후킹
 
 
        const int VK_PROCESSKEY = 0xE5;
        const int WM_IME_COMPOSITION = 0x10F;
        const int WM_IME_ENDCOMPOSITION = 0x10E;
        const int KEYEVENTF_EXTENDEDKEY = 0x1;
        const int KEYEVENTF_KEYUP = 0x2;
        [DllImport("user32.dll")]
        static extern bool keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
 
        [DllImport("user32.dll")]
        static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);
 
        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hInstance);
 
        [DllImport("user32.dll")]
        static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);
 
        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);
 
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
 
        const int WH_KEYBOARD_LL = 13; // Номер глобального LowLevel-хука на клавиатуру
        const int WM_KEYDOWN = 0x100; // Сообщения нажатия клавиши
         
        const int WM_IME_STARTCOMPOSITION = 0x010D;
 
        #region VirtualKey
        public enum VKeys : int
        {
            VK_LBUTTON = 0x01,  //Left mouse button
            VK_RBUTTON = 0x02,  //Right mouse button
            VK_CANCEL = 0x03,  //Control-break processing
            VK_MBUTTON = 0x04,  //Middle mouse button (three-button mouse)
            VK_BACK = 0x08,  //BACKSPACE key
            VK_TAB = 0x09,  //TAB key
            VK_CLEAR = 0x0C,  //CLEAR key
            VK_RETURN = 0x0D,  //ENTER key
            VK_SHIFT = 0x10,  //SHIFT key
            VK_CONTROL = 0x11,  //CTRL key
            VK_MENU = 0x12,  //ALT key
            VK_PAUSE = 0x13,  //PAUSE key
            VK_CAPITAL = 0x14,  //CAPS LOCK key
            VK_HANGUL = 0x15,
            VK_ESCAPE = 0x1B,  //ESC key
            VK_SPACE = 0x20,  //SPACEBAR
            VK_PRIOR = 0x21,  //PAGE UP key
            VK_NEXT = 0x22,  //PAGE DOWN key
            VK_END = 0x23,  //END key
            VK_HOME = 0x24,  //HOME key
            VK_LEFT = 0x25,  //LEFT ARROW key
            VK_UP = 0x26,  //UP ARROW key
            VK_RIGHT = 0x27,  //RIGHT ARROW key
            VK_DOWN = 0x28,  //DOWN ARROW key
            VK_SELECT = 0x29,  //SELECT key
            VK_PRINT = 0x2A,  //PRINT key
            VK_EXECUTE = 0x2B,  //EXECUTE key
            VK_SNAPSHOT = 0x2C,  //PRINT SCREEN key
            VK_INSERT = 0x2D,  //INS key
            VK_DELETE = 0x2E,  //DEL key
            VK_HELP = 0x2F,  //HELP key
            VK_0 = 0x30,  //0 key
            VK_1 = 0x31,  //1 key
            VK_2 = 0x32,  //2 key
            VK_3 = 0x33,  //3 key
            VK_4 = 0x34,  //4 key
            VK_5 = 0x35,  //5 key
            VK_6 = 0x36,  //6 key
            VK_7 = 0x37,  //7 key
            VK_8 = 0x38,  //8 key
            VK_9 = 0x39,  //9 key
            VK_A = 0x41,  //A key
            VK_B = 0x42,  //B key
            VK_C = 0x43,  //C key
            VK_D = 0x44,  //D key
            VK_E = 0x45,  //E key
            VK_F = 0x46,  //F key
            VK_G = 0x47,  //G key
            VK_H = 0x48,  //H key
            VK_I = 0x49,  //I key
            VK_J = 0x4A,  //J key
            VK_K = 0x4B,  //K key
            VK_L = 0x4C,  //L key
            VK_M = 0x4D,  //M key
            VK_N = 0x4E,  //N key
            VK_O = 0x4F,  //O key
            VK_P = 0x50,  //P key
            VK_Q = 0x51,  //Q key
            VK_R = 0x52,  //R key
            VK_S = 0x53,  //S key
            VK_T = 0x54,  //T key
            VK_U = 0x55,  //U key
            VK_V = 0x56,  //V key
            VK_W = 0x57,  //W key
            VK_X = 0x58,  //X key
            VK_Y = 0x59,  //Y key
            VK_Z = 0x5A,  //Z key
            VK_NUMPAD0 = 0x60,  //Numeric keypad 0 key
            VK_NUMPAD1 = 0x61,  //Numeric keypad 1 key
            VK_NUMPAD2 = 0x62,  //Numeric keypad 2 key
            VK_NUMPAD3 = 0x63,  //Numeric keypad 3 key
            VK_NUMPAD4 = 0x64,  //Numeric keypad 4 key
            VK_NUMPAD5 = 0x65,  //Numeric keypad 5 key
            VK_NUMPAD6 = 0x66,  //Numeric keypad 6 key
            VK_NUMPAD7 = 0x67,  //Numeric keypad 7 key
            VK_NUMPAD8 = 0x68,  //Numeric keypad 8 key
            VK_NUMPAD9 = 0x69,  //Numeric keypad 9 key
            VK_SEPARATOR = 0x6C,  //Separator key
            VK_SUBTRACT = 0x6D,  //Subtract key
            VK_DECIMAL = 0x6E,  //Decimal key
            VK_DIVIDE = 0x6F,  //Divide key
            VK_F1 = 0x70,  //F1 key
            VK_F2 = 0x71,  //F2 key
            VK_F3 = 0x72,  //F3 key
            VK_F4 = 0x73,  //F4 key
            VK_F5 = 0x74,  //F5 key
            VK_F6 = 0x75,  //F6 key
            VK_F7 = 0x76,  //F7 key
            VK_F8 = 0x77,  //F8 key
            VK_F9 = 0x78,  //F9 key
            VK_F10 = 0x79,  //F10 key
            VK_F11 = 0x7A,  //F11 key
            VK_F12 = 0x7B,  //F12 key
            VK_SCROLL = 0x91,  //SCROLL LOCK key
            VK_LSHIFT = 0xA0,  //Left SHIFT key
            VK_RSHIFT = 0xA1,  //Right SHIFT key
            VK_LCONTROL = 0xA2,  //Left CONTROL key
            VK_RCONTROL = 0xA3,  //Right CONTROL key
            VK_LMENU = 0xA4,   //Left MENU key
            VK_RMENU = 0xA5,  //Right MENU key
            VK_PLAY = 0xFA,  //Play key
            VK_ZOOM = 0xFB, //Zoom key
        }
        #endregion
 
        private LowLevelKeyboardProc _proc = hookProc;
 
        private static IntPtr hhook = IntPtr.Zero;
 
        public void SetHook()
        {
 
            IntPtr hInstance = LoadLibrary("User32");
            hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0);
        }
 
        public static void UnHook()
        {
            UnhookWindowsHookEx(hhook);
        }
 
        public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
        {
 
            if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN && CommonObj._keyCount <= 0)
            {
                int vkCode = Marshal.ReadInt32(lParam);
 
                //방향키나 엔터키 텝키 일경우에는 후킹 하지 않는다
              VKeys vk_value = (VKeys)vkCode;
                switch (vk_value)
                {
                    case VKeys.VK_RETURN:
                    case VKeys.VK_TAB:
                    case VKeys.VK_UP:
                    case VKeys.VK_DOWN:
                    case VKeys.VK_LEFT:
                    case VKeys.VK_RIGHT:
                    case VKeys.VK_LCONTROL:
                    case VKeys.VK_RCONTROL:
                    case VKeys.VK_DELETE:
                    case VKeys.VK_HANGUL:
                    case VKeys.VK_LSHIFT:
                    case VKeys.VK_RSHIFT:
                         
                    return CallNextHookEx(hhook, code, (int)wParam, lParam);
                         
 
                }
                //사용자의 DataGrid를 EditMode로 전환 한다.
                _dataGrid.BeginEdit();    
                     
                //후킹한 키보드를 강제로 입력 한다.                
                keybd_event((byte)Marshal.ReadByte(lParam), 0, KEYEVENTF_EXTENDEDKEY, 0);
 
                return (IntPtr)1;
            }
            else
                return CallNextHookEx(hhook, code, (int)wParam, lParam);
        }
 
        #endregion

SetHook() 을 호출하면 키보드 후킹이 시작되고, UnHook()를 호출하면 후킹이 종료 된다.

C#프로그램을 하다가 막히면 결국 WinApi를 사용해서 해결해야 하니, 아무래도 윈도우 Application 개발자는 C++(WinApi)을 기본적으로 알면 많은 도움이 될것 같다.


출처: http://enginhak.tistory.com/entry/C-%ED%82%A4%EB%B3%B4%EB%93%9C-%ED%9B%84%ED%82%B9DataGrid-%ED%95%9C%EA%B8%80-%EC%9E%85%EB%A0%A5%EC%9D%84-%EC%9C%84%ED%95%9C

Ex

특정 RectTransform 안에 있는 오브젝트를 마우스위치로 이동시키고자할때

 if (RectTransformUtility.ScreenPointToLocalPointInRectangle(

            this.transform.parent.GetComponent<RectTransform>(),

            new Vector2(Input.mousePosition.x, Input.mousePosition.y),

            parentCanvase.worldCamera,

            out pos))

        {

            this.transform.localPosition = pos;


        }else

        {


        }



RectTransformUtility.ScreenPointToLocalPointInRectangle

public static bool ScreenPointToLocalPointInRectangle(RectTransform rectVector2 screenPointCamera cam, outVector2 localPoint);

Parameters

rectThe RectTransform to find a point inside.
camThe camera associated with the screen space position.
screenPointScreen space position.
localPointPoint in local space of the rect transform.

Returns

bool Returns true if the plane of the RectTransform is hit, regardless of whether the point is inside the rectangle.

Description

Transform a screen space point to a position in the local space of a RectTransform that is on the plane of its rectangle.

The cam parameter should be the camera associated with the screen point. For a RectTransform in a Canvas set to Screen Space - Overlay mode, the cam parameter should be null.

When ScreenPointToLocalPointInRectangle is used from within an event handler that provides a PointerEventData object, the correct camera can be obtained by using PointerEventData.enterEventData (for hover functionality) orPointerEventData.pressEventCamera (for click functionality). This will automatically use the correct camera (or null) for the given event.

출처:

http://docs.unity3d.com/ScriptReference/RectTransformUtility.ScreenPointToLocalPointInRectangle.html

public void writeStringToFile( string str, string filename )
{
#if !WEB_BUILD
string path = pathForDocumentsFile( filename );
FileStream file = new FileStream (path, FileMode.Create, FileAccess.Write);

StreamWriter sw = new StreamWriter( file );
sw.WriteLine( str );

sw.Close();
file.Close();
#endif 
}


public string readStringFromFile( string filename)//, int lineIndex )
{
#if !WEB_BUILD
string path = pathForDocumentsFile( filename );

if (File.Exists(path))
{
FileStream file = new FileStream (path, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader( file );

string str = null;
str = sr.ReadLine ();

sr.Close();
file.Close();

return str;
}

else
{
return null;
}
#else
return null;
#endif 
}

public string pathForDocumentsFile( string filename ) 

if (Application.platform == RuntimePlatform.IPhonePlayer)
{
string path = Application.dataPath.Substring( 0, Application.dataPath.Length - 5 );
path = path.Substring( 0, path.LastIndexOf( '/' ) );
return Path.Combine( Path.Combine( path, "Documents" ), filename );
}

else if(Application.platform == RuntimePlatform.Android)
{
string path = Application.persistentDataPath; 
path = path.Substring(0, path.LastIndexOf( '/' ) ); 
return Path.Combine (path, filename);


else 
{
string path = Application.dataPath; 
path = path.Substring(0, path.LastIndexOf( '/' ) );
return Path.Combine (path, filename);
}
}


출처::http://blog.naver.com/nameisljk/110157303742


SetBkMode(hdc, TRANSPARENT);  //

TextOut ...... 

이런식으로 먼저 하면 된다.


TRANSPARENT 대신에  OPAQUE  사용하면  (OPAQUE 가 디폴트)

SetBkColor 로 선택한 색상이 배경으로 나온다.


출처:http://soen.kr/lecture/win32api/reference/Function/SetBkMode.htm

'부스러기 > WINAPI' 카테고리의 다른 글

더블버퍼링  (0) 2015.05.19

      HCD  hdc = BeginPaint(hWnd, &ps);

HDC backMemDC, MemDC;

static HBITMAP backBitmap = NULL;

HBITMAP  hMyBitmap, hOldBitmap;

RECT crt;

GetClientRect(hWnd, &crt);


MemDC = CreateCompatibleDC(hdc);

hMyBitmap = CreateCompatibleBitmap(hdc, crt.right, crt.bottom);

hOldBitmap = (HBITMAP)SelectObject(MemDC, hMyBitmap);

FillRect(MemDC, &crt, (HBRUSH)GetStockObject(WHITE_BRUSH));


///// 화면 처리작업을 전부 MemDC 쪽으로 한다.

this->render(MemDC);


BitBlt(hdc, 0, 0, crt.right, crt.bottom, MemDC, 0, 0, SRCCOPY);

DeleteObject(SelectObject(MemDC, hOldBitmap));

DeleteDC(MemDC);

EndPaint(hWnd, &ps);




!!! 화면 지우는 작업을 못 해게 해준다. !!

case WM_ERASEBKGND:

return 0;


'부스러기 > WINAPI' 카테고리의 다른 글

TextOut 사용시 배경색없애는 방법  (0) 2015.05.19

Dex Loader] Unable to execute dex: GC overhead limit exceeded


이클립스 내에  eclipse.ini 파일을 열어서 밑에와 같이 수정해보자.

openFile
--launcher.XXMaxPermSize
512M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
512m
--launcher.defaultAction
openFile
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms512m
-Xmx1024m

출처:http://stackoverflow.com/questions/9471194/unable-to-execute-dex-gc-overhead-limit-exceeded

'부스러기 > Java' 카테고리의 다른 글

java dom 파서로 xml 파싱 중 #text 처리  (0) 2019.04.01
Static 키워드  (0) 2017.06.12
JAVA mysql 사용  (0) 2013.07.12

+ Recent posts