Search Results for '프로그래밍'


1206 posts related to '프로그래밍'

  1. 2011/12/06 [UI 설계] Widget, View, Layout 개론
  2. 2011/12/06 ViewPage 예제
  3. 2011/12/06 android TabActivity 의 이해
  4. 2011/12/06 안드로이드 apk decompile 하기 완결판 - APK 디컴파일 하기 JAVA
  5. 2011/12/06 원격서버의 Virtualbox 의 웹관리툴 Phpvirtualbox 관련 삽질
  6. 2011/12/05 SharePoint 2010 설치
  7. 2011/11/23 ABCUpload Component 4.1 1
  8. 2011/11/23 Windows 2000 커맨드 명령어
  9. 2011/11/23 MS-WORD문서를 읽어 들이려면
  10. 2011/11/23 javascript - 자바스트립트 프린터( 프린트 컴포넌트 무료제공 )
  11. 2011/11/23 윈도우 DNS 백업&복구
  12. 2011/11/23 MS-SQL 함수정의
  13. 2011/11/23 MS-SQL 사용자 소유 권한 변경
  14. 2011/11/23 Ms-Sql LDF파일 용량 줄이기
  15. 2011/11/23 Ms-Sql 암호화, 복호화 (PwdEncrypt, PwdCompare)
  16. 2011/11/23 컴포넌트를 이용한 블로그 XML RSS 구현
  17. 2011/11/23 홈페이지 자동링크 함수
  18. 2011/11/23 HTML가져오기 1
  19. 2011/11/23 ASP 페이지를 엑셀로 불러올때 숫자를 문자 형태
  20. 2011/11/23 유용한 ASP소스
  21. 2011/11/19 ASP - 드라이브 용량 알아내기
  22. 2011/11/19 ASP - URL Encode 엔코더
  23. 2011/11/19 ASP 파일 목록(리스트) 얻어오기
  24. 2011/11/19 마우스로 개체 이동 및 크기 변화, 자동 크기변화
  25. 2011/11/19 aspuploader가 유료라 찾은 Free ASP Upload입니다. 1
  26. 2011/11/19 group by와 distinct를 같이 쓸 때 속도 향상법
  27. 2011/11/19 table 구조에서 열(column) 단위로 숨기기
  28. 2011/11/19 [asp] server.urlencode + download
  29. 2011/11/19 우편번호 검색 API 사용예
  30. 2011/11/19 ASP에서 글씨를 그림으로 만들기 [ImageMagick 활용]
ArrayList<string> phone = new ArrayList<string>();
       
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while(cursor.moveToNext())
{
    int index = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
    String s = cursor.getString(index);
    phone.add(s);
}
       
Log.e("#####", phone.toString());
//결과 : [01011112222, 01033334444, 01055556666]
public static Map<String, String> getAddressBook(Context context)
{
    Map<String, String> result = new HashMap<String, String>();
    Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
    while(cursor.moveToNext())
    {
        int phone_idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
        int name_idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
        String phone = cursor.getString(phone_idx);
        String name = cursor.getString(name_idx);
        result.put(name, phone);
    }
   
    return result;
}

2011/12/06 11:24 2011/12/06 11:24

[01] UI 설계(Widget, View, Layout) 개론

View ---+--- View(Widget): 안드로이드가 제공하는 콘트롤, TextView, EditText, Button....
|
+--- Custom View: 기존의 View 를 상속받아 변경하거나 새롭게 생성.
|
+--- ViewGroup --- Layout: View를 배치하고 그룹화 함, LinearLayout, RelativeLayout, TableLayout....

1. UI 설계 방법
- 자바소스상에서 class상에 직접 지정하는 경우와 XML을 이용하는
방법이 있으며 개발과 유지보수의 장점 때문에 XML이 많이 사용된다.
XML을 UI 설계로 이용하는 대표적인 언어는 Flex등이 있다.

2. View
- Widget은 View로 되어있으며 View는 트리구조(상속)를 이루고 있다.
- 모든 안드로이드의 비주얼 콤포넌트는 View 클래스로부터 내려온다.
- View는 Widget, Control이라고 부르기도 한다.
- View --> ViewGroup --> Layout 의 관계를 갖는다.

3. Layout
- ViewGroup class의 확장
- View를 담는 컨테이너 역활을 함.

[02] View
- 화면을 구성하는 UI를 제공한다.
- API: http://developer.android.com/reference/android/view/View.html

1. 공통 XML 속성
- View는 많은 공통 속성과 메소드를 가지고 있는데 TextView의 속성이 대부분의 View에
그대로 적용된다.

android:id : View의 아이디
android:layout_width : 부모뷰를 기준으로 한 폭의 의 크기
android:layout_height : 부모뷰를 높이로한 뷰의 높이
android:padding : 외곽선과 뷰안의 내용과의 간격
android:visibility : 초기화면 표시 여부
android:background : Widget의 배경색을 #RGB, #ARGB, #RRGGBB, #AARRGGBB로 지정
android:clickable : 클릭 가능 여부
android:longClickable : 롱 클릭 가능 여부
android:focusable : 키보드 포커스의 가능 여부

2. 공통 메소드
setEnabled() : Widget의 사용 가능 여부 지정
isEnabled() : Widget이 사용 가능 상태인지 확인
requestFocus(): 해당 Widget으로 입력 포커스 이동
isFocused() : Widget이 현재 포커스를 가지고 있는지 확인
setFocus() : Widget에 focus를 지정
getParent() : 상위 위젯이나 컨테이너 추출
findViewById(): 지정한 id에 대한 위젯 추출
getRootView() : 최상위 컨테이너 추출

3. 레이블
- import android.widget.TextView;
- View --> TextView
- 단순한 문자열의 출력.
- 출력 문자열은 변경할 수 없다.

3. 버튼
- import android.widget.Button;
- 터치 및 클릭 이벤트를 처리한다.
- View --> TextView --> Button
- TextView를 상속받으며 사용자의 tab(터치) 이벤트를 주로 처리한다.

4. 이미지
- import android.widget.ImageView;
- View --> ImageView: 이미지를 넣을 수 있는 View Class
- View --> ImageView --> ImageButton: 이미지를 넣을 수 있는 버튼 클래스

5. 입력 필드
- import android.widget.EditText;
- View --> TextView --> EditText
- 문자를 입력 받을 수 있는 기능 제공

1) XML 속성
android:autoText : 자동 철자 교정
android:capitalize : 첫 글자를 대문자로 변환
android:digits : 특정 숫자만 입력
android:singleLine : 여러줄을 입력받을 것인지 지정
android:numeric : 숫자만 입력 가능
android:password : 패스워드 입력 형태 지정
android:phoneNumber: 전화번호 입력
android:inputMethod: 특정 형식의 입력 지정

6. 체크 박스
- import android.widget.CheckBox;
- View --> TextView --> Button --> CompoundButton
--> RadioButton --> CheckBox
- 취미같은 다중 선택 가능

7. 라디오 버튼
- import android.widget.RadioButton;
- View --> TextView --> Button --> CompoundButton --> RadioButton
- 성별같은 단일 선택만 가능
- RadioGroup에 의해 RadioButton의 그룹화 가능

[03] Layout
- android.view.ViewGroup class 상속 받음.

1. 공통 특성
android:layout_height : 부모 뷰 기준, 자식 뷰에 적용, 뷰의 높이.
android:layout_width : 부모 뷰 기준, 자식 뷰에 적용, 뷰의 너비, 자식뷰의 경우 필수임.
android:layout_margin : 부모 뷰 기준, 뷰의 상하 좌우의 여백 공간.
android:layout_marginTop : 부모 뷰 기준, 뷰의 위쪽 여백 공간.
android:layout_marginBottom: 부모 뷰 기준, 뷰의 아래쪽 여백 공간.
android:layout_marginRight : 부모 뷰 기준, 뷰의 오른쪽 여백 공간 .
android:layout_marginLeft : 부모 뷰 기준, 뷰의 왼쪽 여백 공간.
android:gravity : 자식 뷰 기준, View로 부터의 위치.
android:layout_gravity : 부모 뷰 기준, 현재 View의 위치.

2. AbsoluteLayout: View가 x,y좌표에 의해서 배치, 레이아웃이 깨질 수 있고 화면의
구성요소가 서로 잘 맞아 떨어저야함으로 잘 사용되지 않는다.
안드로이드 SDK 1.5 R1부터 폐기 대상으로 분류되어 더이상 사용되지 않는다.

3. FrameLayout: View를 좌측 상단에 배치, 여러개의 View가 있는 경우 겹쳐서 보임으로
Layout의 효과는 떨어짐, 사용 빈도는 적음.

4. LinearLayout: 직선형의 배치 방식, View를 수평 또는 수직의 라인을 View를 배치,
입력 양식에 많이 사용된다.
android:orientation: 뷰가 출력될 방향을 지정한다.

5. RelativeLayout: 다른 콘트롤에 비례해서 콘트롤의 위치 지정.
- 뷰를 위치를 설정하기위해 여러번 선언 가능.

- 부모뷰를 기준으로
android:layout_marginRight="20px" : 뷰를 부모의 오른쪽에서 일정 간격 떨어짐
android:layout_marginTop="60px" : 뷰를 부모의 위쪽에서 일정 간격 떨어짐
android:layout_alignParentTop="true" : 뷰를 부모에서 상단에 배치
android:layout_centerHorizontal="true" : 뷰를 부모에서 수평 중앙에 배치
android:layout_alignParentRight="true" : 뷰를 부모에서 오른쪽에 배치
android:layout_alignParentLeft="true" : 뷰를 부모에서 왼쪽에 배치
android:layout_centerVertical="true" : 뷰를 부모에서 수직 중앙에 배치
android:layout_centerInParent="true" : 뷰를 수직, 수평의 중앙에 배치
android:layout_alignParentBottom="true": 뷰를 부모에서 하단에 배치

- 주변에 배치된 뷰를 기준으로
android:layout_toRightOf="@id/idname" : 주변 특정 뷰의 오른쪽에 배치
android:layout_toLeftOf="@id/idname" : 주변 특정 뷰의 외쪽에 배치
android:layout_alignBaseline="@id/idname": 주변 특정 뷰와 같은 라인에 배치
android:layout_below="@id/idname" : 주변 특정 뷰의 아래에 배치
android:layout_above="@id/idname" : 주변 특정 뷰의 위에 배치
android:layout_alignRight="@id/idname" : 주변 특정 뷰의 오른쪽에 배치
android:layout_alignLeft="@id/idname" : 주변 특정 뷰의 왼쪽에 배치
android:layout_alignTop="@id/idname" : 주변 특정 뷰의 위쪽에 배치

- 예) [TEL][SMS]의 경우
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnSms"
android:layout_marginLeft="1px"
android:text="SMS"
android:textSize="16px"
android:layout_alignParentRight="true"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnTel"
android:layout_marginLeft="6px"
android:text="TEL"
android:textSize="16px"
android:layout_toLeftOf="@id/btnSms"
/>

6. TableLayout: 행과 열의 격자를 이용해 View의 배치.
- 아래의 레이아웃 특성을 조합하여 사용

android:stretchColumns="1" : 두번째 컴럼의 크기를 남는 공간으로 늘림(확장).
android:stretchColumns=" 늘리려는 column 번호(0~), *"
android:shrinkColumns=" 필요한 공간만 사용하고 줄이고자 하는 column 번호(0~), *"

android:stretchColumns="1" android:shrinkColumns="*": 모든 컬럼의 값을 전부
필요한 만큼만 사용하고 1번째 컬럼을 남은 공간으로 전부 확대

android:collapseColumns=" 숨기고자 하는 column 번호(0~), *"

android:layout_span=" 차지하려는 Column 수", 셀 합치기
android:layout_span="2": 컬럼 2개를 합침.



이름:[ ]의 경우 2번째 입력란을 확대함.
android:layout_marginTop="60px" : 뷰를 부모의 위쪽에서 일정 간격 떨어짐
android:layout_alignParentTop="true" : 뷰를 부모에서 상단에 배치
android:layout_centerHorizontal="true" : 뷰를 부모에서 수평 중앙에 배치
android:layout_alignParentRight="true" : 뷰를 부모에서 오른쪽에 배치
android:layout_alignParentLeft="true" : 뷰를 부모에서 왼쪽에 배치
android:layout_centerVertical="true" : 뷰를 부모에서 수직 중앙에 배치
android:layout_centerInParent="true" : 뷰를 수직, 수평의 중앙에 배치
android:layout_alignParentBottom="true": 뷰를 부모에서 하단에 배치


2011/12/06 11:23 2011/12/06 11:23

1. ViewPage Layout 기술

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical"

>

<android.support.v4.view.ViewPager

android:id="@+android:id/viewpager"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

/>

</LinearLayout>

2. FragmentActivity 기술
/**
*
*/
package com.andy.fragments.viewpager;
import java.util.List;
import java.util.Vector;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import com.andy.R;
import com.andy.fragments.tabs.Tab1Fragment;
import com.andy.fragments.tabs.Tab2Fragment;
import com.andy.fragments.tabs.Tab3Fragment;
/**
* The <code>ViewPagerFragmentActivity</code> class is the fragment activity hosting the ViewPager
* @author mwho
*/
public class ViewPagerFragmentActivity extends FragmentActivity{
/** maintains the pager adapter*/
private PagerAdapter mPagerAdapter;
/* (non-Javadoc)
* @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  super.setContentView(R.layout.viewpager_layout);
  //initialsie the pager
  this.initialisePaging();
}
/**
* Initialise the fragments to be paged
*/
private void initialisePaging() {
  List<Fragment> fragments = new Vector<Fragment>();
  fragments.add(Fragment.instantiate(this, Tab1Fragment.class.getName()));
  fragments.add(Fragment.instantiate(this, Tab2Fragment.class.getName()));
  fragments.add(Fragment.instantiate(this, Tab3Fragment.class.getName()));
  this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);
  //
  ViewPager pager = (ViewPager)super.findViewById(R.id.viewpager);
  pager.setAdapter(this.mPagerAdapter);
}
}
3. PageAdapter 기술
/**
*
*/
package com.andy.fragments.viewpager;
import java.util.List;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
/**
* The <code>PagerAdapter</code> serves the fragments when paging.
* @author mwho
*/
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
/**
* @param fm
* @param fragments
*/
public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
  super(fm);
  this.fragments = fragments;
}
/* (non-Javadoc)
* @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(int position) {
  return this.fragments.get(position);
}
/* (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount() {
  return this.fragments.size();
}
}
4.실행
왼쪽에서 오른쪽은 빨강->녹색->파랑
2011/12/06 11:23 2011/12/06 11:23

사용자 삽입 이미지

이것은 안드로이드 Tab UI 를 구성하는 구성요소 입니다.

안드로이드 Tab UI 는 이와같이 세 개의 다른 클래스들의 집합으로 이루어져 있습니다.

TabHost 는 TabUI 를 구성하는 전체 틀 입니다.

여기에는 특정한 android:id 를 가지는 TabWidget 와 TabSpec 이 포함되어야 합니다.

TabWidget 는 TabUI 에서 선택하는 버튼이 나오는 부분을 말하며 이것의 android:id 는 반드시 “@android:id/tabs” 가 되어야 합니다.

TabSpec 는 하나의 탭을 구성하는 구성요소들의 집합으로서 View 의 하위구성요소가 아니기 때문에 layout xml 파일에 직접 추가될 수 없습니다. 그래서 java 소스코드상으로 추가해 주어야 하며 layout xml 에는 이를 표시하기 위하여“@android:id/tabcontent” 라는 android:id 를 가지는 Layout View 가 추가되어 있어야 합니다.

이렇게 글로만 보면 상당히 어렵게 보이는데 이것을 쉽게 쓰도록 만들어 놓은것이 바로 TabActivity 클래스 입니다.

아래는 TabActivity 를 이용하여 layout xml 파일 없이 TabUI 를 구성하는 예 입니다.

package net.cranix.android.cranixcontact;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TabHost;

public class CranixContact extends TabActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

final TabHost tabHost = getTabHost();
tabHost.addTab(
tabHost.newTabSpec("tab1")
.setIndicator("Contacts")
.setContent(new Intent(this,ContactsTabActivity.class))
);
tabHost.addTab(
tabHost.newTabSpec("tab2")
.setIndicator("Calllog")
.setContent(new Intent(this,CalllogTabActivity.class))
);
}
}

위의 소스에는 layout xml 파일이 사용되는 부분이 없지만 TabActivity 내부적으로 기본적인 layout 을 사용하고 있습니다.

그렇다면 TabActivity 에서 사용하는 기본적인 layout 은 무엇일까요?

안드로이드 소스를 직접 다운받아서 xml 파일을 뒤져보면 아래와 같은 레이아웃 파일을 발견할 수 있습니다.

<TabHost xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget android:id="@android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0" />
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
</LinearLayout>
</TabHost>

이것이 바로 TabActivity 클래스가 기본으로 사용하는 layout xml 파일입니다.

위에서 말로 설명한 부분에 나와있는 대로 구성되어있는것을 확인할 수 있습니다.

TabActivity 를 상속받은 Activity 라면 기본적으로 위와같은 layout xml 파일이 contentView 로 자동으로 셋팅됩니다.

이것을 염두해 두고 개발을 해야지 오류를 피할수 있습니다.

그럼 내가만든 layout xml 을 TabActivity 에 띄우는 예제를 만들어 보겠습니다.

먼저 layout 을 구성합니다 파일이름은 main.xml 입니다.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:text="@+id/TextView01"
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button android:text="@+id/Button01"
android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>

이것을 TabActivity 에 띄우는 java 코드는 아래와 같습니다.

package net.cranix.android.testtabactivity;

import android.app.TabActivity;
import android.os.Bundle;
import android.widget.TabHost;

public class TestTabActivity extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
final TabHost tabHost = getTabHost();

getLayoutInflater().inflate(R.layout.main, tabHost.getTabContentView());

tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("tab1").setContent(R.id.TextView01));
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("tab2").setContent(R.id.Button01));
}
}
TabSpec.setContent 에 view 를 지정하려면 반드시 @”android:id/tabcontent” 의 하위 뷰 여야 합니다.
그래서 자신이 만든 layout 을 기존에 있던 tabHost 의 tabContentView 에 inflate 를 활용하여 붙혀주는 것 입니다.

위의 굵은 글씨에 의해 inflat 가 실행된 이후에는 layout 을 아래와 같이 인식합니다.

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget android:id="@android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_weight="0" />
<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
<TextView android:text="@+id/TextView01"
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button android:text="@+id/Button01"
android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
</LinearLayout>
</TabHost>

결국 위와 같이 tabSpec 을 만들때 setContent 에다가 자신이 만든 layout 을 사용할 수 있게 되는것 입니다.

이렇게 TabActivity 가 돌아가는 구조를 알아내면 응용도 가능합니다.

아래 예제는 안드로이드 TabUI 에서 TabWidget 이 아래에 있도록 구성한 Activity 입니다.

먼저 layout 파일은 아래와같이 구성합니다.

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
<TextView android:text="@+id/TextView01"
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button android:text="@+id/Button01"
android:id="@+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
<TabWidget android:id="@android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_weight="0" />
</LinearLayout>
</TabHost>

그다음 Activity 파일은 아래와 같이 구성합니다.

package net.cranix.android.testtabactivity;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TabHost;

public class TestTabActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TabHost tabHost = (TabHost) findViewById(R.id.tabhost);
tabHost.setup();

tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("tab1").setContent(R.id.TextView01));
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("tab2").setContent(R.id.Button01));
}
}

실행해 보면 아래와 같이 탭이 아래에 있는것을 볼 수 있습니다.

사용자 삽입 이미지

여기서 중요한 것은 TabActivity 가 아니라 그냥 Activity 를 이용하였다는 것과 레이아웃 파일을 안드로이드 TabUI 에 맞게 직접 구성했다는점 입니다.

이렇게 TabActivity 를 통하지 않고 Tab 을 구현할 경우에는 반드시 tabHost.setup() 을 호출해 주어야 합니다.

여기서 TabHost view 하위에 있는 기본 뷰를 탐색해서 셋팅해 주게 됩니다.

즉 이 함수를 거치면 tabHost.getTabWidget() 과 tabHost.getTabContentView() 같은 메소드를 사용할때 null 이 반환되지 않게 됩니다.

결국 안드로이드 TabUI 는 기본적인 안드로이드 UI 구조를 가지고 TabUI 를 구성하기 편하게 상속하여 재작성 한 것입니다.

2011/12/06 11:22 2011/12/06 11:22

* 안드로이드을빨리이해하기위한방법

1. OpenSource활용

- http://code.google.com/hosting/

- http://google.com/codesearch

2. Reverse Engineering 활용하여 학습하기

- 자바 클래스 리버싱

사용자 삽입 이미지

- 안드로이드 실행파일 구조와 리버싱

사용자 삽입 이미지

사용자 삽입 이미지

* APK파일 디컴파일(Decompile)하는 방법

1. 디컴파일을 위한 툴 설치

1.ApkTool

- 다운로드 : http://code.google.com/p/android-apktool/downloads/list

사용자 삽입 이미지

- 압축풀기 : android-sdk가 설치된 platform-tools디렉토리안에 apktool디렉토리를 만들어 압축을 푼다.

apktool1.4.1.tar.bz2

apktool-install-windows-r04-brut1.tar.bz2

사용자 삽입 이미지

2.Dex2Jar

- 다운로드 : http://code.google.com/p/dex2jar/downloads/list

사용자 삽입 이미지


- 압축풀기 : android-sdk가 설치된 platform-tools디렉토리안에 dex2jar디렉토리를 만들어 압축을 푼다.

dex2jar-0.0.7.10-SNAPSHOT.zip

사용자 삽입 이미지

3.Java Decompiler

- 다운로드 : http://java.decompiler.free.fr/?q=jdgui

사용자 삽입 이미지

- 압축풀기 : 실행하기 편한 곳에 압축을 풀어 놓는다.

2. 환경변수 잡기

- adb, apktool, dex2jar 명령어를 사용하기 위한 환경변수를 잡는다.

%ANDROID_SDK%\platform-tools

%ANDROID_SDK%\platform-tools\apktool

%ANDROID_SDK%\platform-tools\dex2jar

 

사용자 삽입 이미지사용자 삽입 이미지

3. apk 파일 추출

- 폰에 설치된 모든 패키리를 리스트로 보인다.

사용자 삽입 이미지

- 리스트 중에 디컴파일 할 APK파일을 정한다.

사용자 삽입 이미지

- APK파일을 추출한다. (adb shell을 종료 후 수행한다.)

사용자 삽입 이미지

4. ApkTool 실행 (java파일 외 xml, image, db등을 추출할 수 있다.)

- apktool 명령어를 사용하여 apk파일에 있는 파일을 디코딩하여 out폴더에 내보낸다.

사용자 삽입 이미지

사용자 삽입 이미지

- xml파일을 열어 내용을 확인한다.

사용자 삽입 이미지

5. Dex2Jar 실행 (Java파일을 추출할 수 있다.)

- apk파일의 확장자를 zip으로 변경한다.

사용자 삽입 이미지

- 추출한 zip파일의 압축을 풀어 classes.dex 파일을 추출한다.

사용자 삽입 이미지

- Dex2Jar를 실행한다.

사용자 삽입 이미지

- Dex2Jar를 실행하면 아래 jar파일이 생긴다.

사용자 삽입 이미지

6. JD-GDI 실행

- JD-GDI실행하여 classes.dex.dex2jar파일을 열어 소스를 분석한다.

사용자 삽입 이미지

7. Enterprise Architect를 이용하여 클래스 다이어그램으로 분석한다.

- 다운로드 : http://www.sparxsystems.com.au/products/ea/trial.html

사용자 삽입 이미지

- 설치

사용자 삽입 이미지

- 실행

사용자 삽입 이미지

- Java Decompiler에서 open할 파일을 추출한다.

사용자 삽입 이미지

- zip파일을 압축을 푼다.

사용자 삽입 이미지

- Enterprise Architect에서 classes.dex.dex2jar.src디렉토리를 import 한다.

사용자 삽입 이미지

- 클래스 다이어그램을 보고 분석한다.

사용자 삽입 이미지

-----------------------------------------------------------------------------------------------------------------------

제 11회 한국자바개발자 컨퍼런스에서 트랙1, 3번째 세션에서 Reverse Engineering, 안드로이드 학습이란 주제로 발표를 진행합니다.

리버싱이 무엇인지, 안드로이드 리버싱을 통해서 어떻게 학습을 할 수 있는지 다양한 도구와 팁들을 소개합니다.

학습을 목적으로 리버스엔지니어링이 허용되지만 기술을 복제 유혹을 받을 수도 있습니다.

법적이나, 윤리적으로 문제가 된다는 것을 명심하고, 공부한 내용을 서로 공유하며 미소 지을 수 있는 개발문화가 되길 바래봅니다. :D

발표자료와 함께 사용된 동영상 공유합니다.

발표자료 : Reverse Engineering, 안드로이드 학습

자바 클래스 리버싱

안드로이드 실행파일 구조와 리버싱

Reverse Engineering 활용한 학습 예제

  1. 분석할 앱선정과 APK 파일 추출
  2. 디컴파일 후 분석
  3. 클래스 다이어그램으로 - Enterprise Architect
  4. 의존성 검사를 통해 쉽게 - xDepend
2011/12/06 11:18 2011/12/06 11:18
###########################################################################
### 쓴건 : 원격서버의 Virtualbox 웹관리를 위한 Phpvirtualbox 설치
### 쓴이 : 권성재 (nonots@hanmail.net, http://www.badaweb.co.kr)
### 쓴때 : 2011-12-13
###########################################################################

### 환경
- CentOS 5.x 64비트
- 아파치 2.2, PHP 5.2
- X 윈도우(GUI) 없이 텍스트모드(TUI)로 서버 실행중


1) 서버 CPU 가 가상화기술을 지원하는지 확인. 지원 안한다면 포기.
# egrep '(vmx|svm)' /proc/cpuinfo


2) php 확장기능에 soap, json 이 포함되어 있는지 확인. 없다면 추가 설치.
php 버전도 5.1 이상이어야 한다.
# php -i | egrep -i '(soap|json)'


3) dkms 패키지 설치
아래 링크에서 다운받아 설치
- http://rpmfind.net/linux/rpm2html/search.php?query=dkms
- http://linux.dell.com/dkms/permalink/
# rpm -Uvh dkms-~~~.rpm


4) VirtualBox 4.1 및 확장팩 설치
-http://download.virtualbox.org/virtualbox/
글쓰는 현재 최신버전이 4.1.6 이다. 확장팩도 같이 다운받는다
# rpm -Uvh VirtualBox-4.1-4.1.6_74727_rhel5-1.x86_64.rpm

-확장팩 설치
# VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-4.1.6-74713.vbox-extpack

부가기능 설치 위한 VBoxGuestAdditions_4.1.6.iso 파일도
다운받아 놓는다.

- vbox 사용자 추가하고 비밀번호 정한다. 비번을 kawkf123 이라고 하자
# useradd -g vboxusers vbox
# passwd vbox
만약 홈디렉토리를 /home/vbox 가 아니라 용량큰 다른 곳에 마운트한
/data/vbox 와 같은 위치를 사용한다면 -d /data/vbox 와 같이 추가

- /etc/vbox/vbox.cfg 파일 생성
[root@home3 ~]# cat /etc/vbox/vbox.cfg
VBOXWEB_USER=vbox
VBOXWEB_HOST=222.231.xxx.xxx
VBOXWEB_PORT=18083
VBOXWEB_LOGFILE=/var/log/vbox.log

와 같이 하고 반드시 /var/log/vbox.log 를 만들어줌
# touch /var/log/vbox.log
# chmod 600 /var/log/vbox.log
# chown vbox.vboxusers /var/log/vbox.log
이렇게 안만들어주고 데몬시작하니 말도 없이 까칠하게 생깜.
VBOXWEB_HOST=222.231.xxx.xxx 이 부분을
VBOXWEB_HOST=0.0.0.0 으로 하기도 한담.
18083 포트가 막혀있으면 열어준다.


5) Phpvirtualbox 4.1 설치
- http://code.google.com/p/phpvirtualbox/
위 링크에서 phpvirtualbox-4.1-5.zip 다운받아서 웹루트 적당한 곳에
압축을 푼다.
만약 Virtualbox 4.0 이 설치되었다면 phpvirtualbox 도 4.0 버전대를 사용
해야 할꺼다.
config.php-sample 파일을 config.php 로 복사한 후 편집기로 열어서 상단에

var $username = 'vbox';
var $password = 'kawkf123';
var $location = 'http://222.231.xxx.xxx:18083/';`

여기 username,password 는 4)에서 생성한 리눅스 서버 vbox 계정정보다.

이 웹접속 위치가 http://www.mysite.com/phpvirtualbox/index.php 라고 하자

어떤데서는 아래 명령어 줘야한다고함. vbox 계정으로 전환한 뒤 해야하거나.
# VBoxManage setproperty websrvauthlibrary null


6) 접속방법

# /etc/init.d/vboxballoonctrl-service start
# /etc/init.d/vboxdrv start
# /etc/init.d/vboxweb-service start
와 같이 데몬을 시작한다.
만약 위 3)에서 dkms 커널모듈이 설치가 불안정하게 되었다면
# /etc/init.d/vboxdrv setup 로 재설치할 수도 있다.
위 3 개 데몬 실행에 오류가 없고 18083 포트가 열렸고,프로세스가
# ps aux |grep vbox
vbox 32002 0.0 0.1 149588 4268 ? Sl 18:26 0:00 /usr/lib/virtualbox/vboxwebsrv --background -H 222.231.xxx.xxx -p 18083 -F /var/log/vbox.log
vbox 32007 0.0 0.0 119560 2200 ? S 18:26 0:00 /usr/lib/virtualbox/VBoxXPCOMIPCD
vbox 32012 0.0 0.1 140076 5620 ? Sl 18:26 0:00 /usr/lib/virtualbox/VBoxSVC --auto-shutdown
와 같이 보이면 일단 된거다.

http://www.mysite.com/phpvirtualbox/index.php 와 같이 접속하면
로그인 아이디 비번 물을꺼다.
여기에 위에서 vbox 서버 계정 정보를 넣으려고 삽질하면 안.된.다. 나처럼 -_-;;
아이디 비번에 모두 admin 이라고 넣어야 한다.
로그인후 메뉴에서 admin 비밀번호를 바꾸면 된다.
보이는 화면은 그냥 virtualbox 와 비슷할꺼다.
..
이제 알아서 직관적으로 사용하면 된다.




### 참고
http://codefat.com/tag/phpvirtualbox/
http://www.oss.kr/12792
2011/12/06 09:39 2011/12/06 09:39

[System Requirement]

Software requirements

Windows Server 2008 R2 or Windows Server 2008 SP2 이상

SQL 2005 640bit with SP2 or SQL 2008 64bit SP1 + 누적패치(hotfix) or SQL 2008 R2 64-bit

.NET 3.5 with SP1

Hardware requirements

This part is very short since it applies to

  • a single server with built-in database and
  • Server farm installations including a single server or multiple servers.

So according to Microsoft TechNet [1] you need:

  • Processor
    Beta:
    64-bit, dual processor, 3 GHz
    RTM: 64-bit, four cores
  • RAM
    4 GB for stand-alone or evaluation installation
    and 8 GB for single server and multiple server farm installation for production use
  • Hard disk
    80 GB
  • Other
    DVD drive

[설치 환경]

Windows Server 2008 R2

SQL Server 2008 SP1

[사전 준비 작업]

IIS 추가

응용 프로그램 서버 추가

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

SQL 2008 설치

사용자 삽입 이미지
 

SQL 2008 SP1: http://www.microsoft.com/downloads/details.aspx?displaylang=ko&FamilyID=66ab3dbb-bf3e-4f46-9559-ccc6a4f9dc19

IE ESC 구성 - 사용 안함

사용자 삽입 이미지
 

[SharePoint 2010 설치]

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

재부팅 후 프로그램 설치가 자동으로 진행

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

서버 팜 선택

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

[SharePoint 제품 구성 마법사]

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

SQL 2008 SP1 version: 10.0.2541.0

SQL 2008 SP1 누적패치(hotfix) 구하는 방법: http://support.microsoft.com/kb/970315

SQL 패치 후 SharePoint 제품 구성 마법사를 다시 실행하여 제품 구성을 다시 진행

패스워드 복잡성 및 8자 이상 요구

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

사용자 삽입 이미지
 

팀 사이트

사용자 삽입 이미지
 

2011/12/05 18:15 2011/12/05 18:15
최신 버전이 있긴 하지만. 최신 버전은 30일 날짜 제한이 있어서..
4.1을 올렸음.
2011/11/23 19:32 2011/11/23 19:32
Windows 2000 커맨드 명령어의 모든것

Windows 2000의 커멘드 명령어는 MS-DOS의 대부분의 기능을 유지시키거나 발전시켰다.
아래의 표의 내용은 MS-DOS에 없는 새로운 Windows 2000 명령, MS-DOS에서 변경된 명령, 사용할 수 없는 MS-DOS 명령들을 나타낸다.

Windows 2000의 새로운 명령

이 표는 MS-DOS에 없는 Windows 2000만의 시스템 명령을 나타낸다.

명령 기능
at 지정된 시간과 날짜에 컴퓨터에서 명령과 프로그램을 실행하도록 예약한다.
cacls 파일의 액세스 컨트롤 목록(ACL)을 표시하거나 수정한다.
convert 파일 시스템을 FAT나 FAT32에서 NTFS로 변환한다.
dosonly Command.com 프롬프트에서 MS-DOS 기반이 아닌 응용 프로그램을 시작할 수 없게 한다.
echoconfig MS-DOS 하위 시스템 Config.nt 파일을 읽을 때 메시지를 표시한다.
endlocal 환경 변수의 지역화를 끝낸다.
findstr 정규식을 사용하여 파일에서 텍스트를 검색한다.
ntcmdprompt TSR을 실행한 후나 MS-DOS 응용 프로그램 내에서 명령 프롬프트를 시작한 후에 Command.com 대신 Windows 2000 명령 인터프리터인 Cmd.exe를 실행한다.
popd 가장 최근의 pushd 명령으로 설정된 디렉터리로 변경한다.
pushd popd 명령에 사용할 수 있도록 현재 디렉터리를 저장한 다음 지정된 디렉터리로 변경한다.
setlocal 환경 변수의 지역화를 시작한다.
start 보조 창과 보조 창 고유의 메모리 공간에 지정된 프로그램이나 명령을 실행한다.
Title 명령 프롬프트 창의 제목을 설정한다.
&& 이 기호 뒤의 명령은 기호 앞의 명령이 성공한 경우에만 실행된다.
|| 이 기호 뒤의 명령은 기호 앞의 명령이 실패한 경우에만 실행된다.
& 명령줄의 여러 명령을 구분한다.
( ) 명령들을 그룹화한다.
^ 제어 문자. 명령 기호를 텍스트로 입력할 수 있도록 한다.
; 또는 , 매개 변수를 구분한다.

MS-DOS 명령 변경 사항

이 표는 변경되거나 성능이 향상된 MS-DOS 명령 목록이다.

명령 변경된 기능
chcp 전화면 모드 전용 코드 페이지를 변경한다.
cmd Cmd.exe는 Command.com을 대신한다.
del 새 스위치들이 더 많은 기능을 제공한다.
dir 새 스위치들이 더 많은 기능을 제공한다.
diskcomp /1/8 스위치를 지원하지 않는다.
diskcopy /1 스위치를 지원하지 않는다.
doskey 버퍼 입력을 받아들이는 모든 문자 기반 프로그램에서 사용할 수 있습니다. doskey는 여러 기능들이 향상되었습니다.
format 20.8MB 광드라이브를 지원한다. /b, /s/u 스위치를 지원하지 않는다.
label 볼륨 레이블에 ^ 및 & 기호를 사용할 수 있습니다.
mode 많은 변경 사항이 있습니다.
more 새 스위치들이 더 많은 기능을 제공한다.
path 명령 프롬프트에서 %PATH% 환경 변수는 현재 경로를 새 설정에 추가한다.
print /b, /c, /m, /p, /q, /s, /t/u 스위치를 지원하지 않는다.
prompt 앰퍼샌드($a), 괄호($c 및 $f)와 공백($s)을 프롬프트에 추가할 수 있도록 새 문자 조합을 허용한다.
recover 파일만 복구한다.
rmdir 새로운 /s 스위치는 파일과 하위 디렉터리를 포함하고 있는 디렉터리를 삭제한다.
sort TEMP 환경 변수가 필요하지 않는다. 파일 크기에 제한이 없다.
xcopy 새 스위치들이 더 많은 기능을 제공한다.

사용할 수 없는 MS-DOS 명령

명령 프롬프트에서 다음 MS-DOS 명령들은 사용할 수 없다.

명령 새로운 절차 또는 사용하지 않는 이유
assign Windows 2000에서는 지원되지 않는다.
backup 현재 지원되지 않는다.
choice 현재 지원되지 않는다.
ctty 현재 지원되지 않는다.
dblspace 지원되지 않는다.
defrag Windows 2000은 자동으로 디스크 사용을 최적화한다. 수동으로 디스크를 최적화하려면 내 컴퓨터에서 디스크를 마우스 오른쪽 단추로 눌러 등록 정보를 클릭한 다음 도구 탭에서 지금 조각 모음을 클릭한다.
deltree rmdir /s 명령으로 파일과 하위 디렉터리를 포함하고 있는 디렉터리를 삭제한다.
diskperf 현재 지원되지 않는다.
dosshell Windows 2000에서는 필요 없다.
drvspace Drvspace 프로그램은 현재 지원되지 않는다.
emm386 Windows 2000에서는 필요 없다.
fasthelp 이 MS-DOS 6.0 명령은 Windows 2000의 help 명령과 동일한다. Windows 2000은 온라인 명령 목록도 제공한다.
fdisk 디스크 관리로 Windows 2000에서 하드 디스크를 사용할 수 있도록 준비한다.
include MS-DOS 하위 시스템의 다중 구성은 지원되지 않는다.
interlnk Interlnk 프로그램은 지원되지 않는다.
intersrv Intersrv 프로그램은 지원되지 않는다.
join 증가된 파티션 크기와 향상된 파일 시스템으로 드라이브를 조인할 필요가 없다.
memmaker Windows 2000은 자동으로 MS-DOS 하위 시스템의 메모리 사용을 최적화한다.
menucolor MS-DOS 하위 시스템의 다중 구성은 지원되지 않는다.
menudefault MS-DOS 하위 시스템의 다중 구성은 지원되지 않는다.
menuitem MS-DOS 하위 시스템의 다중 구성은 지원되지 않는다.
mirror Windows 2000에서는 지원되지 않는다.
msav Msav 프로그램은 지원되지 않는다.
msbackup Windows 2000은 테이프 드라이브가 있는 컴퓨터를 위해(제어판의 관리 도구에서) 백업 유틸리티를 제공하며 테이프 드라이브가 없는 컴퓨터를 위해 xcopy 명령을 제공한다.
mscdex CD-ROM 드라이브를 사용하기 위해 MS-DOS 하위 시스템을 구성할 필요가 없다. Windows 2000은 MS-DOS 하위 시스템에 CD-ROM 드라이브 액세스를 제공한다.
msd 시스템 정보 스냅인을 사용한다. 시스템 정보를 시작하려면 시작, 실행을 클릭한 다음 msinfo32를 입력한다.
numlock 현재 지원되지 않는다.
power Power 유틸리티는 지원되지 않는다.
restore 현재 지원되지 않는다.
scandisk Scandisk 유틸리티는 지원되지 않는다.
smartdrv Windows 2000은 자동으로 MS-DOS 하위 시스템에 캐시 기능을 제공한다.
submenu MS-DOS 하위 시스템의 다중 구성은 지원되지 않는다.
sys Windows 2000은 표준 1.2MB나 1.44MB 플로피 디스크에 적당하지 않는다.
undelete Windows 2000에서는 지원되지 않는다.
unformat Windows 2000에서는 지원되지 않는다.
vsafe Vsafe 프로그램은 지원되지 않는다.
2011/11/23 18:47 2011/11/23 18:47
OLE Automation을 이용

보통 컴포넌트를 이용하는 방법, Type Library를 사용하는 Early binding, IDispatch인터폐이스를

이용하는 late binding이 있습니다.

온라인상이라 다 설명하기는 빌더 Server탭에 있는 컴포넌트에 대해서만 설명드리겠습니다.

Server탭에 WordApplication 컴포넌트를 폼에 떨어드리시고 다음과 같이 코딩하세요

void __fastcall TForm1::OpenWordClick(TObject *Sender)
{
WordApplication1->Connect(); //워드개체와 연결
WordApplication1->Visible = true; //화면에 보이게
WordApplication1->Documents->Open(&TVariant("C:\\QFD.doc")); //파일불러오기
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CloseWordClick(TObject *Sender)
{
WordApplication1->Disconnect(); //워드개체 닫기
}
//---------------------------------------------------------------------------
2011/11/23 18:46 2011/11/23 18:46

// JavaScript Document
// Body에 object함수 호출
function object()
{
document.write("<object id='factory' style='display:none' classid='clsid:1663ed61-23eb-11d2-b92f-008048fdd814' codebase='http://www.meadroid.com/scriptx/smsx.cab'>");
document.write("</object>");
}

function printWindow()
{
factory.printing.header = "" // 머릿글
factory.printing.footer = "" // 바닥글
factory.printing.portrait = true // true 세로출력 , false 가로출력
factory.printing.leftMargin = 10
factory.printing.topMargin = 10
factory.printing.rightMargin = 10
factory.printing.bottomMargin = 10

factory.printing.Print( true, window ) // 대화상자 표시여부 / 출력될 프레임명
}

-----------------------------------------

예)

<HEAD>

<SCRIPT language="javascript" src="FactoryPrint.js"></SCRIPT>

</HEAD>

<BODY>

<SCRIPT language="javascript">

object(); // <BODY> 바로밑에서 호출

</SCRIPT>

</BODY>

printWindow() 함수에서 셋팅을 한후

호출하면 프린트가 됨.

2011/11/23 18:46 2011/11/23 18:46

DNS 백업&복구

DNS백업
1. DNS 서비스 중지
2. regedit 실행
3. HKEY_LOCAL_MACHINE\SYSYEM\CirrentcControlSet\Servies\DNS 폴더를 내보내기 선택."DNS1"이라는 파일 이름으로 저장
4. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Currentversion\DNS Server 폴더를 내보내기 선택. "DNS2"라는 파일이름으로 저장
5. Windows\System32\DNS 디렉터리를 찾아서 확장자가 .dns인 모든파일복사
6. DNS 재시작.

DNS복구
1. 복사한 .dns확장자를 가진 파일을 Windows\System32\DNS에 복사
2. DNS서비스를 중지
3. .reg 확장자를 가진 두개의 파일을 클릭. 그리고 레지스트리에 설치 되었는지 확인.
4. DNS 서비스를 재시작.

2011/11/23 18:45 2011/11/23 18:45

MSSQL 함수 사용 및 예문들입니다.

환경은 MS-SQL2005 입니다
※ 문자열 함수 정리

1) Ascii() - 문자열의 제일 왼쪽 문자의 아스키 코드 값을 반환(Integer)
예) SELECT Ascii('abcd')

>> 결과는 a의 아스키 코드값인 97 반환

2) Char() - 정수 아스키 코드를 문자로 반환(Char)
예) SELECT Char(97)

>> 결과는 a 반환

3) Charindex() - 문자열에서 지정한 식의 위치를 반환
예) SELECT Charindex('b','abcde') >> 결과 : 2
SELECT Charindex('b','abcde',2) >> 결과 : 2
SELECT Charindex('b','abcde',3) >> 결과 : 0

-- 인수값이 3개일때 마지막은 abcde 에서의 문자열 검색 시작위치를 말하며
2인경우는 bcde 라는 문자열에 대해서 검색
3인 경우는 cde 라는 문자열에 대해서 검색 하게 된다.

4) Difference() - 두 문자식에 SUONDEX 값 간의 차이를 정수로 반환

예) SELECT Difference('a','b')

5) Left() - 문자열에서 왼쪽에서부터 지정한 수만큼의 문자를 반환

예) SELECT Left('abced',3) 결과 >> 3

6) Len() - 문자열의 길이 반환

예) SELECT Len('abced') 결과>>5

7) Lower() - 대문자를 소문자로 반환

예) SELECT Lower('ABCDE') 결과 >> abcde

8) Ltrim() - 문자열의 왼쪽 공백 제거

예) SELECT Ltrim(' AB CDE') 결과>> AB CDE

9)Nchar() - 지정한 정수 코드의 유니코드 문자 반환

예) SELECT Nchar(20) 결과 >>

10) Replace - 문자열에서 바꾸고 싶은 문자 다른 문자로 변환

예) SELECT Replace('abcde','a','1') 결과>>1bcde

11) Replicate() - 문자식을 지정한 횟수만큼 반복

예) SELECT Replicate('abc',3) 결과>> abcabcabc

12) Reverse() - 문자열을 역순으로 출력

예) SELECT Reverse('abcde') 결과>> edcba

13) Right() - 문자열의 오른쪽에서 부터 지정한 수 만큼 반환(Left() 와 비슷 )

예) SELECT Right('abcde',3) 결과>> cde

14)Rtrim() - 문자열의 오른쪽 공백 제거

예) SELECT Rtrim(' ab cde ') 결과>> ' ab cde' <-- 공백구분을위해 ' 표시

15) Space() - 지정한 수만큼의 공백 문자 반환

예) SELECT Space(10) 결과 >> ' ' -- 그냥 공백이 나옴

확인을 위해서 SELECT 'S'+Space(10)+'E' 결과 >> S E

16) Substring() - 문자,이진,텍스트 또는 이미지 식의 일부를 반환

예) SELECT Substring('abcde',2,3) 결과>> bcd

17)Unicode() - 식에 있는 첫번째 문자의 유니코드 정수 값을 반환

예)SELECT Unicode('abcde') 결과 >> 97

18)Upper() - 소문자를 대문자로 반환

예) SELECT Upper('abcde') 결과>> ABCDE

※ 기타 함수 Tip

19) Isnumeric - 해당 문자열이 숫자형이면 1 아니면 0을 반환

>> 숫자 : 1 , 숫자X :0

예) SELECT Isnumeric('30') 결과 >> 1

SELECT Isnumeric('3z') 결과 >> 0

20) Isdate() - 해당 문자열이 Datetime이면 1 아니면 0
>> 날짜 : 1 , 날짜 X :0
예) SELECT Isdate('20071231') 결과 >> 1

SELECT Isdate(getdate()) 결과 >> 1
SELECT Isdate('2007123') 결과 >> 0

SELECT Isdate('aa') 결과 >> 0

※ 날짜및 시간함수 정리

getdate() >> 오늘 날짜를 반환(datetime)

1> DateAdd() - 지정한 날짜에 일정 간격을 + 새 일정을 반환

예) SELECT Dateadd(s,2000,getdate())

2> Datediff() - 지정한 두 날짜의 간의 겹치는 날짜 및 시간 범위 반환

예)SELECT DateDiff(d,getdate(),(getdate()+31))

3> Datename() -지정한 날짜에 특정 날짜부분을 나타내는 문자열을 반환

예) SELECT Datename(d,getdate())

4> Datepart() -지정한 날짜에 특정 날짜부분을 나타내는 정수를 반환

예) SELECT Datepart(d,getdate())

>> Datename , Datepart 은 결과 값은 같으나 반환 값의 타입이 틀림.

5> Day() -지정한 날짜에 일 부분을 나타내는 정수를 반환

예) SELECT Day(getdate()) -- 일 반환

SELECT Month(getdate()) -- 월 반환

SELECT Year(getdate()) -- 년 반환

6> Getutcdate() -현재 UTC 시간을 나타내는 datetime 값을 반환

예) SELECT Getutcdate()

2011/11/23 18:44 2011/11/23 18:44
exec sp_changeobjectowner '소유자.테이블명','변경후소유자'
exec sp_changeobjectowner 'getmeout.mem_staff_rank_temp','dbo'
2011/11/23 18:44 2011/11/23 18:44
use testdb

-- DB 정보 보기
exec sp_helpdb testdb

-- LDF 파일 크기 줄이기 -- 트랜잭션 로그파일을 10메가로 생성
backup log testdb with TRUNCATE_ONLY
DBCC SHRINKFILE ([testdb_Log], 10)

-- MDF 파일 크기 줄이기
DBCC SHRINKDATABASE(testdb)

-- MS-SQL의 ldf 파일 용량 줄이기
-- 트랜잭션 로그파일 최소의 단위로 축소
backup log testdb with truncate_only

-- 트랜잭션 로그파일을 삭제
backup log testdb with no_log

-- 트랜잭션 로그파일을 10메가로 생성
dbcc shrinkfile (testdb_log, 10)

DBCC SHRINKFILE (file_name, target_size)
DBCC SHRINKDATABASE (database_name, target_percent)

2011/11/23 18:43 2011/11/23 18:43
Ms-Sql의 컬럼을 암호화하기 위한 내장함수가 있다.

-PwdEncrypt : 컬럼의 데이터를 암호화한다. ex. PwdEncrypt('암호화할 데이터')
-PwdCompare : 암호화한 데이터를 비교해서 확인한다. ex. PwdCompare('데이터', 암호화컬럼)

간단 예제

create table TEST (
password varchar(100)
);

테이블을 만든 후

insert into TEST values (PwdEncrypt('1111'));

데이터를 암호화하여 넣은 후 select해보자

select PwdCompare('1111', password) from TEST
결과 : 1

select PwdCompare('2222', password) from TEST
결과 : 0

PwdCompare의 결과는 1이나 0으로 리턴된다. 1이면 맞는거고 0이면 틀린것이다.
2011/11/23 18:43 2011/11/23 18:43
꼭 블로그가 아니더라도 XML RSS 는 이제 어느정도 대세가 되어가고 있는 듯합니다. 이제는 언론사나 커뮤니티 등에서도 RSS 가 나옵니다.. 그리고 #Reader나 Xpyder,FreeDemon 등의 RSS 구독기 또한 점차 넓게 사용되고 있습니다. 여기서는 이러한 XML RSS 를 구현하는 방법을 ASP 기반에서 XML 컴포넌트를 이용하여 구현하고자 합니다.

사실 RSS 를 구현할때 사실 단순히 텍스트 파일로 뿌려주고 ContentType 만 xml 로 선언해줘도 가능합니다. 그러나 조금은 다르게 해보고 싶다는 저의 호기심도 있고, 확장성과 향후 유지보수에 조금이라도 더 손쉽게 하기위해서 윈도우즈 2000 에 기본제공되어 있는 XML 관련 컴포넌트를 이용하여 구현해보았습니다. 물론 아래 소스는 지금 제 블로그 RSS 의 원형이 되고 있습니다.

한가지 주의 하실점은 XML 선언전에 어떠한 개행(\n) 이나 문자가 들어가서는 안됩니다. PHP 에서의 쿠키과 마찬가지 입니다.

<?xml version="1.0" encoding="EUC-KR" ?>
<%
Response.ContentType = "text/xml"
Set xmlPars = Server.CreateObject("Msxml2.DOMDocument")

' 여기서 부터 rss 정보를 담는다.
Set rss = xmlPars.CreateElement("rss")
rss.setAttribute "version", "2.0"
rss.setAttribute "xmlns:dc", "http://purl.org/dc/elements/1.1/"
rss.setAttribute "xmlns:sy", "http://purl.org/rss/1.0/modules/syndication/"
rss.setAttribute "xmlns:admin", "http://webns.net/mvcb/"
rss.setAttribute "xmlns:rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlPars.AppendChild(rss)

'<channel> 시작

Set Channel = xmlPars.CreateElement("channel")
rss.AppendChild(Channel)

'<title>정보
Set title = xmlPars.CreateElement("title")
Channel.AppendChild(title)
Channel.childnodes(0).text = "블로그 제목"

'<link>정보
Set channel_link = xmlPars.CreateElement("link")
Channel.AppendChild(channel_link)
Channel.childnodes(1).text = "블로그 주소"

'<description>정보
Set description = xmlPars.CreateElement("description")
Channel.AppendChild(description)
Channel.childnodes(2).text = "블로그 설명"

'<dc:language>정보
Set language = xmlPars.CreateElement("dc:language")
Channel.AppendChild(language)
Channel.childnodes(3).text = "ko"

'<image>정보
Set image = xmlPars.CreateElement("image")
Channel.AppendChild(image)

'이미지 정보에 들어갈 것들
set i_title = xmlPars.CreateElement("title")
set i_url = xmlPars.CreateElement("url")
set i_width = xmlPars.CreateElement("width")
set i_height = xmlPars.CreateElement("height")

image.AppendChild(i_title)
image.AppendChild(i_url)
image.AppendChild(i_width)
image.AppendChild(i_height)

image.childnodes(0).text = "이미지 제목"
image.childnodes(1).text = "이미지 경로"
image.childnodes(2).text = "이미지 가로 사이즈"
image.childnodes(3).text = "이미지 세로 사이즈"

' 여기서 부터는 포스트에 대해서 출력

' 우선 데이터를 읽어오자
SQL = "해당되는 포스트에 대한 쿼리문"
set rs = Server.CreateObject("ADODB.Recordset")
rs.Open SQL,접근문자열,adOpenForwardOnly,adLockPessimistic,adCmdText

' 여기서 부터 루프를 돌리자.
Do until rs.EOF

'<item> 이라는 노드를 추가
Set item = xmlPars.CreateElement("item")
Channel.AppendChild(item)

' 여기서부터 해당 포스트의 세부 정보를 출력
set title = xmlPars.CreateElement("title") '
set link = xmlPars.CreateElement("link")
set description = xmlPars.CreateElement("description")
set dcdate = xmlPars.CreateElement("dc:date")
set dcsubject = xmlPars.CreateElement("dc:subject")

item.AppendChild(title)
item.AppendChild(link)
item.AppendChild(description)
item.AppendChild(dcdate)
item.AppendChild(dcsubject)

item.childnodes(0).text = rs("제목필드")
item.childnodes(1).text = rs("포스트 고유 url 필드")
item.childnodes(2).text = rs("내용 필드")
item.childnodes(3).text = rs("날짜")
item.childnodes(4).text = rs("포스트의 분류")

rs.movenext
loop

' 마지막으로 최종적으로 뿌려주자.
Response.Write xmlPars.xml

'마무리 ^^;

rs.close

set rs = nothing

Set xmlPars = nothing
%>

2011/11/23 18:42 2011/11/23 18:42
<%

Function RegExpContent(str)

Dim ptrn, repstr

ptrn = "((http|https|ftp|telnet|news):\/\/[a-z0-9-]+\.[][a-zA-Z0-9:&#@=_~%;\?\/

\.\+-]+)"

repstr = "<a href=""$1"" target=""_blank"">$1</a>"

RegExpContent = ReplaceEreg(ptrn, repstr, str)

End Function

Function ReplaceEreg(ptrn, repstr, str)

Dim regEx

Set regEx = New RegExp

regEx.Pattern = ptrn

regEx.IgnoreCase = True

regEx.Global = True

ReplaceEreg = regEx.Replace(str, repstr)

End Function

content = "다음은 asprun 홈페이지 주소이다. http://www.naver.com/ 기억해주세요"

content = RegExpContent(content)

content = "<pre>"& content &"</pre>"

response.write content

%>

2011/11/23 18:41 2011/11/23 18:41

<%
' ===========================
' Function to GetHTMLBin
' ===========================
Function GetHTMLBin(URLaddress)

Dim Http

Set Http = CreateObject("Microsoft.XMLHTTP")
Http.Open "GET", URLaddress, False
Http.Send
GetHTMLBin = Http.responseBody
Set Http = Nothing
End Function

' ===========================
' Function to BinToText
' ===========================
Function BinToText(varBinData, intDataSizeInBytes) ' as String

Const adFldLong = &H00000080
Const adVarChar = 200

Set objRS = CreateObject("ADODB.Recordset")
objRS.Fields.Append "txt", adVarChar, intDataSizeInBytes, adFldLong
objRS.Open
objRS.AddNew
objRS.Fields("txt").AppendChunk varBinData
BinToText = objRS("txt").Value
objRS.Close
Set objRS = Nothing

End Function

GetURL = trim(cizleUrl)&"?CHNL_ID="&trim(CHNL_ID)&"&CHNL_PWD="&trim(CHNL_PWD)&"&CHNL_CD="&trim(CHNL_CD)&"&USER_ID="&chk_id
HTMLBin = GetHTMLBin(GetURL)
html = BinToText(HTMLBin,32000)

Response.write html & "<BR>"
%>

2011/11/23 18:41 2011/11/23 18:41
ASP 페이지를 엑셀로 불러올때 숫자를 문자 형태

mso-number-format:\@

mso-number-format:"0\.000"

mso-number-format:\#\,\#\#0\.000

mso-number-format:"mm\/dd\/yy"

mso-number-format:"d\\-mmm\\-yyyy"

mso-number-format:Percent

ex)

CSS style sheet:

td.accountnum

{mso-number-format:\@}

<td class="accountnum">01070000<td>

2011/11/23 18:40 2011/11/23 18:40

'===================================================================
'== 설명 : 문장을 해당 자릿수만큼 <br>이 들어간 문장으로 변환
'== 이름 : MakeBr(Str,Pos)
'== 변수 : Str(String),Pos(Int)
'== 반환 : String
'===================================================================
Function MakeBr(Str,Pos)

Dim StrLen, TmpStr, i, Midcnt, Start, Surplus

StrLen = len(Str)

If (StrLen Mod Pos) = 0 then
MidCnt = Fix(StrLen/Pos)
Else
MidCnt = Fix(StrLen/Pos) + 1
End If

for i = 1 to MidCnt
if i = 1 then
TmpStr = TmpStr&Mid(Str,i,pos)&"<br>"
Else
TmpStr = TmpStr&Mid(Str,((i-1)*Pos)+1,pos)&"<br>"
End If
next

MakeBr = TmpStr
End Function

' ##################################################################################
' 검색에서 selected
' ##################################################################################
Function getSelected(search,t)
if search = t then
getSelected ="selected"
end if
End function

' ##################################################################################
' checked
' ##################################################################################
Function getChecked(tag,y)
If tag = y then
getChecked = "checked"
End if
End function

' ##################################################################################
' 자동링크
' ##################################################################################

FUNCTION autolink(CONTENT)

DIm Re
Set re = New RegExp

' First Pass for http
re.Pattern = "(\w+):\/\/([^/:]+)(:\d*\b)?([^# \n<]*).*\n"
re.Pattern = "http://([0-9a-zA-Z./@:~?&=_-]+)"
re.Global = True
re.IgnoreCase = True

' ASP seems to be not supporting .MultiLine method.
're.MultiLine = True

CONTENT = re.Replace(CONTENT,"<a target=_blank href='http://$1'>http://$1</a>")

' Second Pass for mail
re.Pattern = "([_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*)@([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)"
autolink = re.Replace(CONTENT,"<a href='mailto:$1@$3'>$1@$3</a>")

END FUNCTION

' ##################################################################################
' 문자열 체크 (리턴값:boolean)
' ##################################################################################
Function chkStrFlag(Val, chkStr)
Dim flag, MyPos

If Val = "" then
flag = false
Else
Mypos =Instr(Val,chkStr)
If MyPos = 0 then
flag=false
Else
flag=true
End If
End If

chkStrFlag = flag
End Function

'##################################################################################
' 문자열 체크 (공백이나 NULL값 체크)
' Val : 체크 값, r_Val (대체값)
'##################################################################################
Function replaceVal(val, r_Val)
Dim flag, MyPos

If (val = "") or IsNull(Val) then
replaceVal = r_Val
Else
replaceVal = val
End If
End Function

'##################################################################################
' 숫자값 자릿수만큼 문자로 변경 (공백이나 NULL값 체크)
' Val : 체크 값, chkLen 자릿수 , r_Val(대체값)
'##################################################################################
Function chkLenReplaceVal(val,chkLen, r_Val)
Dim chkCnt, MyPos
chkCnt = len(Cstr(val))

If chkCnt < chkLen then
chkLenReplaceVal = val

for i = 1 to (chkLen-chkCnt)
chkLenReplaceVal = r_Val&chkLenReplaceVal
next
Else
chkLenReplaceVal = val
End If

End Function

'##################################################################################
' 널값,""값 확인
' Val : 체크 값
' retun 값 : true, false
'##################################################################################
Function chkBlank(val)
If (val = "") or IsNull(Val) then
chkBlank = true
Else
chkBlank = false
End If
End Function

'##################################################################################
' 비교값 리턴
' Val : 체크 값
' retun 값 : true, false 또는 대치 문장
'##################################################################################
Function replaceStr(str, chkStr, replaceStr1, replaceStr2)
If str = chkStr then
replaceStr = replaceStr1
Else
replaceStr = replaceStr2
End If
End Function

'##################################################################################
' NULL값 만들기
' Val : 값
' retun 값 : NULL, 문장
'##################################################################################

Function makeNull(str)
If str="" or IsNull(str) then
makeNull = "NULL"
Else
makeNull = str
End IF
End Function

'##################################################################################
' HTML 태그 지우기 (정규식표현)
' 인자 : strHTML:문장, patrn : 패턴 문장
' retun 값 : String
'##################################################################################

Function stripHTML(strHTML, patrn)
Dim objRegExp, strOutput
Set objRegExp = New Regexp

objRegExp.IgnoreCase = True
objRegExp.Global = True
objRegExp.Pattern = patrn

'objRegExp.Pattern = "<.+?>" '' 태그완전히없앰

strOutput = objRegExp.Replace(strHTML, "")

stripHTML = strOutput

Set objRegExp = Nothing
End Function

'##################################################################################
' 문자 잘라내기
'##################################################################################
Function CutString(Str,Length,Patten)
If Len(Str) > Length Then
CutString = Left(Str,Length-3) & patten
Else
CutString = Str
End If
End Function

별건 아니구요..그냥 가끔 디버깅시에 쓰는 함수에요
####################################################
Sub DbPrintErrMsg(obj)

Dim errLoop
For Each errLoop In obj.Errors
response.write "#############<br>"
response.write "Error Number: " & errLoop.Number & "<br>"
response.write "Description: " & errLoop.Description & "<br>"
response.write "Source: " & errLoop.Source & "<br>"
response.write "SQL State: " & errLoop.SQLState & "<br>"
response.write "Native Error: " & errLoop.NativeError & "<br>"
response.write "#############<br>"
Next
End Sub

########폼값 확인할때###################
Sub Prt_RequestForm(obj)

Dim item
For Each item In obj
response.write "#############<br>"
response.write item&" : " &obj(item)& "<br>"
response.write "#############<br>"
Next
End Sub
ex) Prt_RequestForm(Request.Form), Prt_RequestForm(Request.QueryString),
Prt_RequestForm(UploadForm)

첨부파일이 없습니다.
2011/11/23 18:40 2011/11/23 18:40

<%
Set fs = Server.CreateObject("Scripting.FileSystemObject")
Set c_drive = fs.GetDrive("c:")
Set g_drive = fs.GetDrive("g:")
Set h_drive = fs.GetDrive("h:")

Dim cmax, gmax, hmax
Dim c, g, h
Dim cper, gper, hper
Dim cfmt, gfmt, hfmt
Dim gbyte
gbyte = 1024*1024*1024

' C, G, H 드라이브 총 용량
cmax = CInt(c_drive.TotalSize / gbyte)
gmax = CInt(g_drive.TotalSize / gbyte)
hmax = CInt(h_drive.TotalSize / gbyte)

' C, G, H 드라이브 남은 용량
c = CInt(c_drive.FreeSpace / gbyte)
g = CInt(g_drive.FreeSpace / gbyte)
h = CInt(h_drive.FreeSpace / gbyte)

'남은 비율 계산
div100 = cmax / 100
cper = CInt(c / div100)
div100 = gmax / 100
gper = CInt(g / div100)
div100 = hmax / 100
hper = CInt(h / div100)

'NTFS, FAT, FAT32등 드라이브 포멧형식
cfmt = c_drive.FileSystem
gfmt = g_drive.FileSystem
hfmt = h_drive.FileSystem

%>
<html>
<head>
<title> 하드 드라이브 용량 알아내기 </title>
</head>

<body style="font-size:9pt;">
<h1>하드 드라이브 용량 체크 예제</h1><p>

<b>C: 드라이브의 용량<b> : <%=cmax%> / <%=c%> GB [남은 비율:<%=cper%>%] 형식:<%=cfmt%><br>
<table border="0" height="50" style="font-size:9pt;" cellspacing="0">
<tr>
<td align="center" bgcolor="#FF0000" width="<%=600-(cper*6)%>">사용 용량(<%=cmax%>GB)</td>
<td align="center" bgcolor="#00FF00" width="<%=cper*6%>">사용 가능 용량(<%=c%>GB)</td>
</tr>
</table>
<p>
<b>G: 드라이브의 용량<b> : <%=gmax%> / <%=g%> GB [남은 비율:<%=gper%>%] 형식:<%=gfmt%><br>
<table border="0" height="50" style="font-size:9pt;" cellspacing="0">
<tr>
<td align="center" bgcolor="#FF0000" width="<%=600-(gper*6)%>">사용 용량(<%=gmax%>GB)</td>
<td align="center" bgcolor="#00FF00" width="<%=gper*6%>">사용 가능 용량(<%=g%>GB)</td>
</tr>
</table>
<p>
<b>H: 드라이브의 용량<b> : <%=hmax%> / <%=h%> GB [남은 비율:<%=hper%>%] 형식:<%=hfmt%><br>
<table border="0" height="50" style="font-size:9pt;" cellspacing="0">
<tr>
<td align="center" bgcolor="#FF0000" width="<%=600-(hper*6)%>">사용 용량(<%=cmax%>GB)</td>
<td align="center" bgcolor="#00FF00" width="<%=hper*6%>">사용 가능 용량(<%=h%>GB)</td>
</tr>
</table>
</body>
</html>

2011/11/19 11:47 2011/11/19 11:47

<html>
<head>
<title> URL encode </title>
</head>

<body>
<h2><font color='blue'>장인수</font></h2><br>
<%=Server.HTMLEncode("<h2><font color='blue'>장인수</font></h2>")%><p>
<%=Server.HTMLEncode("<%=Server.ScriptTimeout%\>")%><p>
<a href="ok.asp?width=<%=Server.URLEncode("50%오십")%>">50%</a><p>
<a href="ok.asp?width=50%오십">50%</a>

</body>
</html>

2011/11/19 11:46 2011/11/19 11:46

<%
Set fs = Server.CreateObject("Scripting.FileSystemObject")
Set folderObj = fs.GetFolder(Server.MapPath("."))
Set files = folderObj.Files
%>
<html>
<head>
<title> 파일 리스트 얻기 예제 </title>
</head>

<body>
<h2><%=Server.MapPath(".")%>디렉토리 목록</h2>
<table border="1" width="900" style="font-size:9pt;" cellpadding="2">
<tr>
<th>이름</th>
<th>크기</th>
<th>형식</th>
<th>생성 시각</th>
<th>마지막 엑세스 시간</th>
<th>마지막 수정 시간</th>
</tr>
<%
For Each file in files
%>

<tr>
<td><a href="<%=file.name%>"><%=file.name%></a></td>
<td><%=file.size%> byte</td>
<td><%=file.type%></td>
<td><%=file.DateCreated%></td>
<td><%=file.DateLastAccessed%></td>
<td><%=file.DateLastModified%></td>
</tr>
<%
Next
%>

</table>
</body>
</html>

2011/11/19 11:45 2011/11/19 11:45

마우스로 개체 이동 및 가로 크기 변화(좌우 개체)에다가

지정된 크기까지 줄여주는 함수를 추가했다.

사용법은 아래와 같다.

e_resize('rightview','leftview','right',400)

function e_resize(leftobjid,rightobjid,direction,limit)

수정 : 가속도 추가 및 함수 간결화

가속도 추가 - 처음엔 빠르다가 나중엔 느림

함수 간결화 - 입력 값을 6개에서 4개로 줄임

입력 값 감소로 인한 오류 발생 -> clreaTimeout 추가

var move=false

var x=0,y=0

function movespan(e){

if(move && movingspanobj!=null){

if(e){

//불여우용

x=e.pageX

y=e.pageY

}

else{

//ie용

x=window.event.clientX

y=window.event.clientY

}

try{

document.selection.empty()

}

catch(e){

window.getSelection().removeAllRanges();

}

//세로 이동

movingspanobj.style.top=y-distance_y

//movingspanobj.style.top=y-20

//가로 이동

movingspanobj.style.left=x-distance_x

//movingspanobj.style.left=((x-movingspanobj.offsetWidth/2)-150)

}

}

function e_resizespan(e){

if(move && movingspanobj!=null){

if(e){

//불여우용

x=e.pageX

}

else{

//ie용

x=window.event.clientX

}

try{

document.selection.empty()

}

catch(e){

window.getSelection().removeAllRanges();

}

//가로 이동

movingspanobj.style.left=x-distance_x

//movingspanobj.style.left=((x-movingspanobj.offsetWidth/2)-150)

var templeftwidth=leftspanwidth-(first_x-x)

var temprightwidth=rightspanwidth+(first_x-x)

//너비 변화

leftspanobj.style.width=templeftwidth

rightspanobj.style.width=temprightwidth

//내부 span 크기 조절

var objs=leftspanobj.getElementsByTagName('span')

for(var i=objs.length;i--;){

objs[i].style.width=templeftwidth

}

objs=rightspanobj.getElementsByTagName('span')

for(var i=objs.length;i--;){

objs[i].style.width=temprightwidth

}

//내부 img 크기 조절

objs=leftspanobj.getElementsByTagName('img')

for(var i=objs.length;i--;){

objs[i].style.width=templeftwidth

}

objs=rightspanobj.getElementsByTagName('img')

for(var i=objs.length;i--;){

objs[i].style.width=temprightwidth

}

}

}

var distance_x,distance_y,movingspanobj,leftspanobj,rightspanobj,leftspanwidth,rightspanwidth,first_x

var e_resize_timeout

document.onmousedown=new Function('move=true')

document.onmouseup=new Function('move=false;movingspanobj=null')

function movethis(spanobj){

if(window.event){

//ie용

x=window.event.clientX

y=window.event.clientY

}

else{

//불여우용

x=e.pageX

y=e.pageY

}

movingspanobj=spanobj

distance_x=x-movingspanobj.offsetLeft

distance_y=y-movingspanobj.offsetTop

movingspanobj.onmousemove=movespan

}

function e_resizethis(spanobj,leftobjid,rightobjid){

if(window.event){

//ie용

x=window.event.clientX

}

else{

//불여우용

x=e.pageX

}

first_x=x

movingspanobj=spanobj

leftspanobj=document.getElementById(leftobjid)

rightspanobj=document.getElementById(rightobjid)

distance_x=x-movingspanobj.offsetLeft

leftspanwidth=leftspanobj.offsetWidth

rightspanwidth=rightspanobj.offsetWidth

movingspanobj.onmousemove=e_resizespan

}

function e_resize(leftobjid,rightobjid,direction,limit){

clearTimeout(e_resize_timeout)

var movesize=0

leftspanobj=document.getElementById(leftobjid)

rightspanobj=document.getElementById(rightobjid)

if((leftspanobj.offsetWidth>limit && direction=='left') || (rightspanobj.offsetWidth>limit && direction=='right')){

if(direction=='left'){

movesize=Math.ceil(Math.abs(leftspanobj.offsetWidth-limit)/20)

leftspanobj.style.width=leftspanobj.offsetWidth-movesize

rightspanobj.style.width=rightspanobj.offsetWidth+movesize

}

else{

movesize=Math.ceil(Math.abs(rightspanobj.offsetWidth-limit)/20)

leftspanobj.style.width=leftspanobj.offsetWidth+movesize

rightspanobj.style.width=rightspanobj.offsetWidth-movesize

}

e_resize_timeout=setTimeout('e_resize("'+leftobjid+'","'+rightobjid+'","'+direction+'",'+limit+')',10)

}

}

2011/11/19 11:41 2011/11/19 11:41

무료인 줄 알았던 aspuploader가 굉장히 비싼 놈이란 걸 알고 나서 찾아 나섰더니

비슷하지만(순수 asp code로 만든 upload) 기능은 upload기능만 있는 무료 프로그램이 있네요.

upload기능만 있으면 되지 다른 거야 뭐...

어차피 다른 것들로 할 때도 구현해 줘야 했던 거니까 (용량 제한이나, 확장자 제한 같은 것들)

단점이라고까지 할 건 아닌 듯.

딱 upload기능만 있기 때문에 뭔가 더 설명할 필요를 못 느끼겠네요.

아래 주소로 가면 받을 수 있습니다.

http://www.freeaspupload.net/

2011/11/19 11:41 2011/11/19 11:41

select

name,

count(distinct ip) visitcount

from member

group by name

위와 같은 query에서 group by와 distinct가 동시에 일어난다.

이렇게 썼을 때 32초 걸리던 query가 27초 걸리도록 줄일 수 있었다.

(DB에서 1초를 넘어 섰다는 건 이미 문제가 있는 거지만 통계 페이지라 일단 통과)

select

name,

count(*) visitcount

from (

select distinct

name,

ip

from member

) a

group by name

distinct를 먼저 한 후에 group by를 했을 때 약간 더 빨랐다.

15~6% 정도...

mssql에서 index 다 태운 상황이었다. (최소한 분석기에서 index 없다는 얘기는 없을 정도)

2011/11/19 11:39 2011/11/19 11:39

display:none;visibility:collapse

ie 기준으로 일부에서는 display:none만 되고 일부에서는 visibility:collapse만 된다.

그래서 두 개 다 쓰니 원하는 대로 된다.

colgroup이나 col tag에 쓰면 된다.

-- 수정 --

실제로 동시에 사용하게 되면 ie8에서는 안 먹는다.

ie8에서 display:none이 안 먹어서 찾은 건데...

none인데 보여주는 건 뭐냐고.

visibility 단독으로 사용하면 된다.

그래서 이렇게 했다.

.hidecol1{display:none}

.hidecol2{visibility:collapse}

function showgroup(id){

if(document.all && (navigator.appVersion.indexOf("MSIE 6.0")>=0 || navigator.appVersion.indexOf("MSIE 7.0")>=0)){

$('colgroup[id!=basic]').addClass('hidecol1')

$('#'+id).removeClass('hidecol1')

}

else{

$('colgroup[id!=basic]').addClass('hidecol2')

$('#'+id).removeClass('hidecol2')

}

}

-- 수정 2 --

위 수정 방식으로 하면 작동은 하는데 7 이하에서 잔상이 남는 현상이 생긴다.

왜 생기는지도 모르겠고 어떻게 없애야 하는지도 모르겠어서

전체 td에 class를 지정해고 class로 선택해서 숨기도록 했다.

위 방법과 비교해도 속도가 상당히 느리다.

var currentclass='player'

function showgroup(targetclass){

$('.'+currentclass).hide()

$('.'+targetclass).show()

currentclass=targetclass

}

2011/11/19 11:38 2011/11/19 11:38
한글 파일을 다운로드 할 때 한글이 깨지는 경우가 생긴다.
이때 파일이름에 server.urlencode를 하면 한글이 깨지지 않는다.
그러나 확장자 뒤에 [1] 혹은 [2] 혹은 [3] 같은 숫자가 붙는다.
원인은 확장자 앞의 .
해결책은 파일 이름과 확장자를 따로 구분해서 파일 이름만 server.urlencode 하기
Response.AddHeader "Content-Disposition","attachment; filename=" & server.urlencode(left(fileName,len(filename)-4)) & right(filename,4)
이런 식으로.
물론 instrrev를 써서 점의 위치를 알아내서 나누는 방법도 있을 수 있고
split을 써서 .을 구분자로 해서 배열 처리하는 방법도 있겠다.
어느 것이 편할 지는 개발자 맘대로.
2011/11/19 11:37 2011/11/19 11:37

우편번호를 찾을 읍/면/동을 입력하세요.

<form method=post action=http://biz.epost.go.kr/KpostPortal/openapi target=postframe>

<input type=hidden name=regkey value=신청하면발급해주는문자열>

<input type=hidden name=target value=post>

<input type=text name=query>

<input type=submit value=검색>

</form>

<iframe name=postframe id=postframe width=600 height=300 frameborder=0 scrolling=yes></iframe>

2011/11/19 11:37 2011/11/19 11:37