Saturday, December 28, 2013

VS 2010에서 jQuery Intellisense 쓰기

jQuery는 목적에 따라 몇 가지 버전의 파일들이 있는데, 그 중에 Visual Studio의
Intellisense를 지원하기 위해 만든 jquery-[version_number]-vsdoc.js가 있다.

(version 2.0.3이라면 jquery-2.0.3-vsdoc.js가 된다)

이것을 jQuery 사이트에서 받아서,

솔루션 디렉터리에 복사한 후
(여기부터 중요)

마우스로 끌어서 Intellisense를 쓰고 싶은 편집 창에 놓으면

다음과 같이 자동으로 ///로 시작하는 주석을 만들어준다. 그러면 그때부터 Intellisense를 쓸 수 있다.

처음 프로젝트를 만들 때부터
도구 -> 라이브러리 패키지 관리자 -> 솔루션용 NuGet 패키지 관리...

에서 jQuery를 설치해 두었으면 자동으로 되는 것이지만 그렇게 해 두지 않았다면

이렇게 파일 별로 수동으로 하는 방법도 있는 것이다.

Saturday, December 21, 2013

드래그앤드롭을 처리할 때는 적절한 threshold를 주는 게 수명 연장에 좋습니다

본론에 들어가기에 앞서,
일반적인 상황-윈도우(컨트롤)가 하나-이라면 이런 문제는 생기지 않는다.
(그래서 지난 번 프로그램에서는 이런 문제가 없었던 거고.)

이번엔 클릭을 인식하는 객체를 모두 컨트롤(Control)로 만들었다. 그랬더니 특이한 결과가 나와서 짜증났왔다.

즉, 이번에는 Movable이라는 클래스를 Control로부터 상속받아 드래그앤드롭을 지원하게 하였다. 여기에 MovableTest를 다시 상속하여 실제 테스트 프로그램에서 사용하였다.

public class Movable : Control {
    override void OnMouseDown(MouseEventArgs e) {...}
    override void OnMouseUp(MouseEventArgs e) {...}
    override void OnMouseMove(MouseEventArgs e) {...}
    override void OnMouseHover(EventArgs e){...}
}

public class MovableTest : Movable {
    override void OnMouseUp(MouseEventArgs e) {
        if(!dragging) { MessageBox.Show("clicked"); }
    }
}

Form1() {
    var mt1 = new MovableTest(new Point(100, 100), new Size(150, 150));
    var mt2 = new MovableTest(new Point(400, 400), new Size(75, 75));
    ...
}

이런 식으로 만드는 것이다.

다른 건 잘 됐는데, 한 컨트롤을 만지다가 다른 컨트롤을 처음으로 클릭하면(very first click이라고 해야 되나, 그러니까 mt1을 드래그하거나, 클릭하거나 하다가 mt2를 클릭하면) 클릭된 효과가 안 나는 것이다(clicked 메시지박스가 안 뜸).

이벤트핸들러를 추가해서 내부 변수들을 추적하는 등의 삽질을 한 끝에...
컨트롤 사이를 전환할 때 클릭만 해도 OnMouseMove가 trigger되는 황당한 현상을 발견했다.
마우스 클릭하다 손 떨리고 그런 거 아니다(이전 프로그램에서는 threshold 따위 없이 살짝이라도 움직이면 드래그로 판정해버렸기 때문에 내 손이 문제인 건 아니다(...)).

결국 OnMouseMove에서 드래깅 여부를 판별할 때 적당한 threshold를 주어 그 값 이상일 때만 dragging으로 인정함으로써 해결하였다.

Control의 특성이라고 생각하고 넘어가기로 한다.


짜증짜증짜증

그러니까 여러분은 Invalidate(Rectangle)을 멀리하고 Invalidate(void)와 더블버퍼링 속성을 가까이하는 게 좋습니다

Rectangle 계산 열심히 해서 영역 최소화해 봤자 Update()를 안 처먹음.

그렇다고 Application.DoEvents() 해버리면 Invalidate(Rectangle)을 하는 의미가 없잖아.




Math.Min, Math.Abs를 안 해도 되니까 차라리 Invalidate(void) + 더블버퍼링이 좋을 거라고 생각하고 그냥 넘어간다. 아오 빡쳐.



EDIT: main form뿐 아니라 개별 control 별로 double buffering 설정을 할 수 있다.

ctor에서 라고만 쓰면 된다.

Sunday, December 15, 2013

IE 10에서 URL encoding (GET에서)

ajax로 GET을 보냈는데 IE에서만 한글 입력 전달이 안 된다.
인코딩 문제는 아니다(이미 meta charset=utf-8).
혹시나 해서 GET을 POST로 바꾸어 줬더니 IE에서도 잘 된다.
아, URL 인코딩 문제로군!

javascript에서 url 인코딩하는 함수는 encodeURI, encodeURIComponent가 있다.

이 부분에서 쓸 것이므로 encodeURIComponent로 조조 부분만 인코딩해주기로 한다.

주의할 점은, key-value pair를 인코딩할 때 ?, = 등은 빼고 따로 해 주어야 한다는 것이다. 즉,
이것을 인코딩할 때,
이렇게 해야지,
이렇게 하면 안 된다는 것이다(keyword에 해당하는 부분도 한글이라면 그 부분만 따로 encodeURIComponent해야 한다).

IE에서만 문제가 되는 이유는 아마도 크롬의 javascript 엔진이 ajax로 GET/POST를 할 때 알아서 url을 인코딩해주기 때문인 듯. (인터넷을 대충 뒤져 보니 스펙에 없으니 IE의 잘못이라기보다는 크롬의 센스인 것 같다. 어디까지나 대충이다.)

이것을 고치면서 한 가지 재미있는 사실을 알았는데, 구글 크롬에서는 주소창에 실제로는 인코딩된 값을 가지면서 사용자에게 보여줄 때만 한글을 보여준다는 것이다. 즉,
http://localhost:49351/search.php?keyword=조조           ...(1)
이것은 실제로는
http://localhost:49351/search.php?keyword=%EC%A1%B0%EC%A1%B0     ...(2)
이것이다.
(1)을 IE의 주소창에 넣으면 실행되지 않지만 (2)를 IE의 주소창에 넣으면 실행된다. 
그러면 (1)을 크롬의 주소창에 넣으면? (2)로 자동 변환되어 실행되므로 잘 실행된다(!)

이것은 크롬 주소창에서 한글이 포함된 주소를 복사해서 메모장에 붙여 보면 알 수 있다.

Wednesday, December 11, 2013

아 짜증나는 PDO

뭔놈의 row 개수 세기가 이렇게 어렵냐.

SELECT COUNT(*) 하고 나서 뭘 어쩌라는 건지...


PDO 만든 색기는 찢어죽여야 한다.


아 PDO가 문젠지 MySQL이 문젠진 모르겠는데 어쨌든...아...콱



결론은 이거임

$STH_SELECT = $dbh->query("SELECT count(*) FROM Table");
$Count = $STH_SELECT->fetchColumn();
http://stackoverflow.com/questions/10956934/select-count-sum-using-php-pdo
(prepare, execute 쓰는 놈은 사살! (탕탕))
이놈의 거 PDO로 한다고 prepare, execute 해 보다가 삽질만 수십 번 했다. 1)


SO를 보다 보면 이거 말고도 질문/답변이 매우 다양하다. 원래 특효약이 없는 질환일수록 치료법이 다양한 법. 개수 구하는 게 그렇게 어려운 일이라니! 게다가 해 보면 나머지는 다 안 됨. PHP 문법은 맞는데 MySQL에서 안 되거나 뭐 그딴 거임. 아오 ActiveX 같은 새끼들...


fetchColumn도 엿같은게 fetchColumn()은 사실 fetchColumn(0)이고,

fetchColumn(i)는 i번째 column을 가져오라는 얘기다.

그럼 row 번호는 뭐야? fetch라는 게 그냥 순서대로 다음 row를 가져오는 거니까 번호 따위는 없는 거다. fetch란 원래 한 번만 하는 게 아니라 계속 하니까 그런 것(미친놈아 그냥 개수 구하랬더니 뭔 fetch를 하고 지랄이여).

애초에 fetchColumn() 같은 걸 만들지 말고 fetchColumn(0)만 허용했어야지.

COUNT 같은 건 정상인의 사고방식이라면 어떤 집합의 속성(property)일 텐데, 이걸 row=0 column=0으로 가져오게 하는 거 자체가 미친 짓이다. SQL이 원래 그렇게 생겨먹긴 했지만 객체지향을 하려면 제대로 해야지. PDO 같은 걸 만들지 말든가.

그러니까 여러분은 MySQL + PHP를 멀리하고 LINQ 짱짱맨을 가까이 하는 게 좋습니다.

빨리 ASP.NET으로 갈아타든지 해야지 이런..


1) GET/POST로 받은 숫자를 WHERE 절에 추가하려고 하는데, prepare/bindParams/execute으로 하니까 숫자랑 문자열을 구분해 줘야 해서 코드가 더러워지고 매우 헷갈린다. 결국 문자열이 될 건데 그렇다고 그냥 문자열로 넣어버리면 멋대로 '를 추가하기 때문에 column이 int 형식이면...


Friday, December 6, 2013

캐시 때문에 망 (크롬 주의)

HTML을 여러 개로 쪼갠 뒤,

Javascript로 필요할 때만 부르게 코드를 짰다.

즉, 한 번이라도 필요하면 쪼개 놓은 HTML 조각을 읽어들이고 그것을 바탕으로 UI 요소(event handler 등)를 만들게 했다.

그리고 HTML 조각 내의 div 중 일부의 name/id를 바꿨다.
(Visual Studio의 리팩터링->이름 변경 같은 게 있으면 얼마나 좋을까!)

그랬더니 (크롬에서) jQuery가 이름을 못 찾는다. (undefined라니 그게 무슨 소리요!)

아무리 뜯어보아도 이상이 없어 IE10으로 실행했더니 된다.

아하 캐시 문제구나.

크롬으로 조각난 HTML (part.html)을 한 번 열어 새로고침 한 후, 원래의 페이지(index.html)를 여러 다시 실행하니 잘 된다.

index.html에서 돌아가는 javascript를 짤 때,

index.html이 아니라 part.html을 고쳤기 때문에 인식을 못한 것인가?

그러면 IE에서는 왜 잘 됐는가?

Wednesday, December 4, 2013

국어와 영어에서의 나열

요즘 기술 서적들을 보면 (번역서라도 그래서는 안 되지만) 번역서가 아닌데도 영어식 나열 방법을 쓰는 게 많다.

~에는 가, 나, 그리고 다가 있다.
가, 나, 그리고 ~했다.
가, 나, 그리고 다는 ~이다.

원서의 문장을 충실히 번역하고자 하는 의지는 가상하나,
저런 것들은 그냥 틀린 문장이라고 봐도 무방하다.

우리말에는 나열되는 구의 종결을 나타내는 조사(주격조사든, 종결어미든*)가 분명히 있기 때문에(이/가, 이다, 있다, 하다, ...) 저런 구분자("그리고")는 필요가 없다.

영어 원문과 비교해 보면 영어에서 마지막 원소(!) 앞에 and 또는 , and가 오는 이유를 알 수 있다.
... are A, B, and C.
~~~~: A, B, and C.
A, B, and C had great time ...
A, B, and C are great authors ...

게다가 1음절인 영어의 and에 비하면 그리고는 무려 3음절이나 된다. 여기에 국어에는 주격조사/종결어미가 추가되므로 음절 손해는 그보다 많다.

비유하자면 Javascript나 PHP에서는 함수를 선언하는 데 function이라는 키워드가 필요하지만 C, C++, C# 등에서는 그런 게 필요 없는 것과 같다.
Javascript에서 웬만하면 ;을 써서 문장을 끝내는 게 좋다는 것도 그렇고...


* 오래 돼서 정확한 용어는 기억이 안 나지만 어쨌든!

Captcha-coin (2)

그 밖에...


자동 디노미네이션이라든가...

Captcha-coin 같은 거 만들면 어떨까

요새 뒤늦게 조명받고 있는 비트코인(Bitcoin)의 가장 큰 문제는, 내가 보기엔, 유용한 자원을 소모하면서 아무 것도 아닌(닐 수도 있는) 것을 만들어낸다는 것이다.

그럴 바에야 Captcha 같은 유용한 일을 할 때마다 자동으로 채굴(적립)되는 시스템을 만들면 어떨까.

그리고 화폐의 원활한 유통을 위해서,

지나치게 오랜 시간 동안, 많은 양을 축적해 두고 있으면 페널티를 주면 좋겠다.

또, 자동 연쇄 징수 시스템도 만들면 좋겠는데 이건 나중에...ㅋ

창 핸들을 만드는 동안 오류가 발생했습니다

System.ComponentModel.Win32Exception was unhandled   MyForm w = new MyForm IntPtr handle = wnd.Handle;   // Exception occurs here class MyFo...