달력

52024  이전 다음

  • 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
실명 인증 기능을 붙이기 위해 작업을 하다보니
외부 업체로 부터 실명 인증 페이지를 받아서 작업하게 되었다

나는 UTF-8로 작업을 해뒀는데 이사람들은 EUC-KR만 지원한단다 -ㅅ-

실명 인증 페이지에서는 정상적으로 한글로 이름이 뜨고 확인이 됐는데
다음 페이지로 넘어오면 □□□ 로 디스플레이 되는 한글 깨짐...

어쩌다 보니 해결은 했다.

EUC-KR 페이지에서
<input type="hidden" name="username" value="<%= UserName%>">

이었던 소스를
<input type="hidden" name="username" value="<%= escape(UserName)%>">
로 escape() 함수를 사용... javascript 에만 있는줄 알았었는데;;;

역시 마찬가지로 받는 페이지 (UTF-8) 에서
UserName = unescape(Request.Form("UserName"))   으로 받아서 해결..

반대로 UTF-8 -> EUC-Kr 일때도 된다고 하는데 해보지는 않았음
Posted by SadDev
|
회원가입을 받는데 완성형 한글만 작성이 가능하도록 하려고 한다.
하지만 모든 데이터는 UTF-8이다보니 아무문제 없이 조합형 한글도 작성이 가능하다
그래서 완성형 한글만 따로 체크를 하는 스크립트를 작성

function chkID()
{
var useTextEn = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQUSTUVWXYZ0123456789';
            var useTextKr = '가각간갇갈갉갊감갑값갓갔강갖갗같갚갛개객갠갤갬갭갯갰갱갸갹갼걀걋걍걔걘걜거걱건걷걸걺검겁것겄겅겆겉겊겋게겐겔겜겝겟겠겡겨격겪견겯결겸겹겻겼경곁계곈곌곕곗고곡곤곧골곪곬곯곰곱곳공곶과곽관괄괆괌괍괏광괘괜괠괩괬괭괴괵괸괼굄굅굇굉교굔굘굡굣구국군굳굴굵굶굻굼굽굿궁궂궈궉권궐궜궝궤궷귀귁귄귈귐귑귓규균귤그극근귿글긁금급긋긍긔기긱긴긷길긺김깁깃깅깆깊까깍깎깐깔깖깜깝깟깠깡깥깨깩깬깰깸깹깻깼깽꺄꺅꺌꺼꺽꺾껀껄껌껍껏껐껑께껙껜껨껫껭껴껸껼꼇꼈꼍꼐꼬꼭꼰꼲꼴꼼꼽꼿꽁꽂꽃꽈꽉꽐꽜꽝꽤꽥꽹꾀꾄꾈꾐꾑꾕꾜꾸꾹꾼꿀꿇꿈꿉꿋꿍꿎꿔꿜꿨꿩꿰꿱꿴꿸뀀뀁뀄뀌뀐뀔뀜뀝뀨끄끅끈끊끌끎끓끔끕끗끙끝끼끽낀낄낌낍낏낑나낙낚난낟날낡낢남납낫났낭낮낯낱낳내낵낸낼냄냅냇냈냉냐냑냔냘냠냥너넉넋넌널넒넓넘넙넛넜넝넣네넥넨넬넴넵넷넸넹녀녁년녈념녑녔녕녘녜녠노녹논놀놂놈놉놋농높놓놔놘놜놨뇌뇐뇔뇜뇝뇟뇨뇩뇬뇰뇹뇻뇽누눅눈눋눌눔눕눗눙눠눴눼뉘뉜뉠뉨뉩뉴뉵뉼늄늅늉느늑는늘늙늚늠늡늣능늦늪늬늰늴니닉닌닐닒님닙닛닝닢다닥닦단닫달닭닮닯닳담답닷닸당닺닻닿대댁댄댈댐댑댓댔댕댜더덕덖던덛덜덞덟덤덥덧덩덫덮데덱덴델뎀뎁뎃뎄뎅뎌뎐뎔뎠뎡뎨뎬도독돈돋돌돎돐돔돕돗동돛돝돠돤돨돼됐되된될됨됩됫됴두둑둔둘둠둡둣둥둬뒀뒈뒝뒤뒨뒬뒵뒷뒹듀듄듈듐듕드득든듣들듦듬듭듯등듸디딕딘딛딜딤딥딧딨딩딪따딱딴딸땀땁땃땄땅땋때땍땐땔땜땝땟땠땡떠떡떤떨떪떫떰떱떳떴떵떻떼떽뗀뗄뗌뗍뗏뗐뗑뗘뗬또똑똔똘똥똬똴뙈뙤뙨뚜뚝뚠뚤뚫뚬뚱뛔뛰뛴뛸뜀뜁뜅뜨뜩뜬뜯뜰뜸뜹뜻띄띈띌띔띕띠띤띨띰띱띳띵라락란랄람랍랏랐랑랒랖랗래랙랜랠램랩랫랬랭랴략랸럇량러럭런럴럼럽럿렀렁렇레렉렌렐렘렙렛렝려력련렬렴렵렷렸령례롄롑롓로록론롤롬롭롯롱롸롼뢍뢨뢰뢴뢸룀룁룃룅료룐룔룝룟룡루룩룬룰룸룹룻룽뤄뤘뤠뤼뤽륀륄륌륏륑류륙륜률륨륩륫륭르륵른를름릅릇릉릊릍릎리릭린릴림립릿링마막만많맏말맑맒맘맙맛망맞맡맣매맥맨맬맴맵맷맸맹맺먀먁먈먕머먹먼멀멂멈멉멋멍멎멓메멕멘멜멤멥멧멨멩며멱면멸몃몄명몇몌모목몫몬몰몲몸몹못몽뫄뫈뫘뫙뫼묀묄묍묏묑묘묜묠묩묫무묵묶문묻물묽묾뭄뭅뭇뭉뭍뭏뭐뭔뭘뭡뭣뭬뮈뮌뮐뮤뮨뮬뮴뮷므믄믈믐믓미믹민믿밀밂밈밉밋밌밍및밑바박밖밗반받발밝밞밟밤밥밧방밭배백밴밸뱀뱁뱃뱄뱅뱉뱌뱍뱐뱝버벅번벋벌벎범법벗벙벚베벡벤벧벨벰벱벳벴벵벼벽변별볍볏볐병볕볘볜보복볶본볼봄봅봇봉봐봔봤봬뵀뵈뵉뵌뵐뵘뵙뵤뵨부북분붇불붉붊붐붑붓붕붙붚붜붤붰붸뷔뷕뷘뷜뷩뷰뷴뷸븀븃븅브븍븐블븜븝븟비빅빈빌빎빔빕빗빙빚빛빠빡빤빨빪빰빱빳빴빵빻빼빽뺀뺄뺌뺍뺏뺐뺑뺘뺙뺨뻐뻑뻔뻗뻘뻠뻣뻤뻥뻬뼁뼈뼉뼘뼙뼛뼜뼝뽀뽁뽄뽈뽐뽑뽕뾔뾰뿅뿌뿍뿐뿔뿜뿟뿡쀼쁑쁘쁜쁠쁨쁩삐삑삔삘삠삡삣삥사삭삯산삳살삵삶삼삽삿샀상샅새색샌샐샘샙샛샜생샤샥샨샬샴샵샷샹섀섄섈섐섕서석섞섟선섣설섦섧섬섭섯섰성섶세섹센셀셈셉셋셌셍셔셕션셜셤셥셧셨셩셰셴셸솅소속솎손솔솖솜솝솟송솥솨솩솬솰솽쇄쇈쇌쇔쇗쇘쇠쇤쇨쇰쇱쇳쇼쇽숀숄숌숍숏숑수숙순숟술숨숩숫숭숯숱숲숴쉈쉐쉑쉔쉘쉠쉥쉬쉭쉰쉴쉼쉽쉿슁슈슉슐슘슛슝스슥슨슬슭슴습슷승시식신싣실싫심십싯싱싶싸싹싻싼쌀쌈쌉쌌쌍쌓쌔쌕쌘쌜쌤쌥쌨쌩썅써썩썬썰썲썸썹썼썽쎄쎈쎌쏀쏘쏙쏜쏟쏠쏢쏨쏩쏭쏴쏵쏸쐈쐐쐤쐬쐰쐴쐼쐽쑈쑤쑥쑨쑬쑴쑵쑹쒀쒔쒜쒸쒼쓩쓰쓱쓴쓸쓺쓿씀씁씌씐씔씜씨씩씬씰씸씹씻씽아악안앉않알앍앎앓암압앗았앙앝앞애액앤앨앰앱앳앴앵야약얀얄얇얌얍얏양얕얗얘얜얠얩어억언얹얻얼얽얾엄업없엇었엉엊엌엎에엑엔엘엠엡엣엥여역엮연열엶엷염엽엾엿였영옅옆옇예옌옐옘옙옛옜오옥온올옭옮옰옳옴옵옷옹옻와왁완왈왐왑왓왔왕왜왝왠왬왯왱외왹왼욀욈욉욋욍요욕욘욜욤욥욧용우욱운울욹욺움웁웃웅워웍원월웜웝웠웡웨웩웬웰웸웹웽위윅윈윌윔윕윗윙유육윤율윰윱윳융윷으윽은을읊음읍읏응읒읓읔읕읖읗의읜읠읨읫이익인일읽읾잃임입잇있잉잊잎자작잔잖잗잘잚잠잡잣잤장잦재잭잰잴잼잽잿쟀쟁쟈쟉쟌쟎쟐쟘쟝쟤쟨쟬저적전절젊점접젓정젖제젝젠젤젬젭젯젱져젼졀졈졉졌졍졔조족존졸졺좀좁좃종좆좇좋좌좍좔좝좟좡좨좼좽죄죈죌죔죕죗죙죠죡죤죵주죽준줄줅줆줌줍줏중줘줬줴쥐쥑쥔쥘쥠쥡쥣쥬쥰쥴쥼즈즉즌즐즘즙즛증지직진짇질짊짐집짓징짖짙짚짜짝짠짢짤짧짬짭짯짰짱째짹짼쨀쨈쨉쨋쨌쨍쨔쨘쨩쩌쩍쩐쩔쩜쩝쩟쩠쩡쩨쩽쪄쪘쪼쪽쫀쫄쫌쫍쫏쫑쫓쫘쫙쫠쫬쫴쬈쬐쬔쬘쬠쬡쭁쭈쭉쭌쭐쭘쭙쭝쭤쭸쭹쮜쮸쯔쯤쯧쯩찌찍찐찔찜찝찡찢찧차착찬찮찰참찹찻찼창찾채책챈챌챔챕챗챘챙챠챤챦챨챰챵처척천철첨첩첫첬청체첵첸첼쳄쳅쳇쳉쳐쳔쳤쳬쳰촁초촉촌촐촘촙촛총촤촨촬촹최쵠쵤쵬쵭쵯쵱쵸춈추축춘출춤춥춧충춰췄췌췐취췬췰췸췹췻췽츄츈츌츔츙츠측츤츨츰츱츳층치칙친칟칠칡침칩칫칭카칵칸칼캄캅캇캉캐캑캔캘캠캡캣캤캥캬캭컁커컥컨컫컬컴컵컷컸컹케켁켄켈켐켑켓켕켜켠켤켬켭켯켰켱켸코콕콘콜콤콥콧콩콰콱콴콸쾀쾅쾌쾡쾨쾰쿄쿠쿡쿤쿨쿰쿱쿳쿵쿼퀀퀄퀑퀘퀭퀴퀵퀸퀼큄큅큇큉큐큔큘큠크큭큰클큼큽킁키킥킨킬킴킵킷킹타탁탄탈탉탐탑탓탔탕태택탠탤탬탭탯탰탱탸턍터턱턴털턺텀텁텃텄텅테텍텐텔템텝텟텡텨텬텼톄톈토톡톤톨톰톱톳통톺톼퇀퇘퇴퇸툇툉툐투툭툰툴툼툽툿퉁퉈퉜퉤튀튁튄튈튐튑튕튜튠튤튬튱트특튼튿틀틂틈틉틋틔틘틜틤틥티틱틴틸팀팁팃팅파팍팎판팔팖팜팝팟팠팡팥패팩팬팰팸팹팻팼팽퍄퍅퍼퍽펀펄펌펍펏펐펑페펙펜펠펨펩펫펭펴편펼폄폅폈평폐폘폡폣포폭폰폴폼폽폿퐁퐈퐝푀푄표푠푤푭푯푸푹푼푿풀풂품풉풋풍풔풩퓌퓐퓔퓜퓟퓨퓬퓰퓸퓻퓽프픈플픔픕픗피픽핀필핌핍핏핑하학한할핥함합핫항해핵핸핼햄햅햇했행햐향허헉헌헐헒험헙헛헝헤헥헨헬헴헵헷헹혀혁현혈혐협혓혔형혜혠혤혭호혹혼홀홅홈홉홋홍홑화확환활홧황홰홱홴횃횅회획횐횔횝횟횡효횬횰횹횻후훅훈훌훑훔훗훙훠훤훨훰훵훼훽휀휄휑휘휙휜휠휨휩휫휭휴휵휸휼흄흇흉흐흑흔흖흗흘흙흠흡흣흥흩희흰흴흼흽힁히힉힌힐힘힙힛힝';

    var obj = document.getElementById('txtid');
    var val = obj.value;
    var chk = 0;
    for(i = 0; i < val.length; i++)
    {
        chk = 0;
        var v = val.charAt(i);
       
        for(j = 0; j < useTextEn.length; j++)
        {
            var v2 = useTextEn.charAt(j);
            if(v == v2)
            {
                chk++;
                break;
            }
        }
       
        for(j = 0; j < useTextKr.length; j++)
        {
            var v2 = useTextKr.charAt(j);
            if(v == v2)
            {
                chk++;
                break;
            }
        }
        if(chk == 0)
        {
            alert('사용 할 수 없는 문자');
            break;
        }
    }
}


순간 이게 머야~~ 라고 놀란 분도 있겠지만...
영문 a~z와 숫자 0~9 완성형 한글 2850자이다...

for문을 돌면서 체크를 하고 오류를 뱉어낸다.

간단한 유저 아이디 체크 같은 경우 큰 부하 없이 체크가 가능하지만.
게시판의 게시물 내용같은 긴 문장 검색하면 부하가 엄청날것 같다 ;;
Posted by SadDev
|

CHttpConnection 을 이용해 asp 페이지로 한글을 보내고 이를 처리하는 과정에서 문제가 발생했다.
asp 페이지에 값이 null로 넘어옴으로 인해 데이터 처리가 불가능해지는 현상이었다..
이를 해결하기 위해 4시간여 구글링을 하면서 이것 저것 테스트 해본결과 성공적인 결과를 주는 한가지 셋팅을 찾아서 포스팅 한다..

1. 서버

기존 소스

char cpURL[128];
DWORD dwServiceType, dwRet;
INTERNET_PORT nPort;
CString ServerStr, ObjectStr, DataStr;
IString UserID, URL, Email, SQLComm, MSG;
BYTE BType;
int iError;

URL.Format("http://server.com/page.asp?id=%s&type=%d",UserID.ToChar(), BType);

sprintf(cpURL, "%s", URL.ToChar());
AfxParseURL(cpURL, dwServiceType, ServerStr, ObjectStr, nPort);
 
CString HeaderStr = "Content-Type: application/x-www-form-urlencoded";
CInternetSession Session("My Session", PRE_CONFIG_INTERNET_ACCESS);
CHttpConnection *pServer = NULL;
CHttpFile *pFile = NULL;

pServer = Session.GetHttpConnection(ServerStr, nPort);
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST, ObjectStr, 0, 1, 0, 0, INTERNET_FLAG_RELOAD);
pFile->AddRequestHeaders(HeaderStr);
pFile->SendRequest();
pFile->QueryInfoStatusCode(dwRet);
  
Session.Close();
delete pFile;
delete pServer;

==================================================
수정 소스

/// 우선 char를 UTF로 변경한다. 그리고 url은에서 파라미터는 제외 한다.
UserID.StringUtf8();    // *char를 utf8로 변경 (회사 내부 소스라 죄송;; 하지만 인터넷 뒤져 보면 나옴.)
URL.Format("
http://server.com/page.asp");
sprintf(cpURL, "%s", URL.ToChar());
AfxParseURL(cpURL, dwServiceType, ServerStr, ObjectStr, nPort);
/// 파라미터를 별도의 CStrig으로 저장
MSG.Format("id=%s&type=%d",UserID.ToChar(), BType); 
DataStr = (LPCTSTR)MSG.ToChar();
  
CString HeaderStr = "Content-Type: application/x-www-form-urlencoded";
CInternetSession Session("My Session", PRE_CONFIG_INTERNET_ACCESS);
CHttpConnection *pServer = NULL;
CHttpFile *pFile = NULL;

pServer = Session.GetHttpConnection(ServerStr, nPort);   // ServerStr =  http://server.com/
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST, ObjectStr);   // ObjectStr = page.asp
pFile->SendRequest(HeaderStr,(LPVOID)(LPCTSTR)DataStr, DataStr.GetLength());  //DataStr = id=아이디&type=type
pFile->QueryInfoStatusCode(dwRet);



page.asp 소스에서
<% @language='vbscript' codepage = '65001' %>
<%      response.charset = "utf-8" %>
이 두줄을 추가한다.

=================================

수정 내용을 종합하면 Char* 를 UTF-8로 변경하고.
URL의 파라미터를 별도로 분리해서 SendRequest 에서 처리하고.
asp 에서는 UTF-8로 받는 소스를 추가...

이렇게 해서 해결됐다 !

'프로그래밍 > C++ / C' 카테고리의 다른 글

[C++/C] 트랜잭션 ...  (0) 2010.12.23
[C++/C] 중복되지 않게 랜덤 숫자 출력  (0) 2010.07.08
Posted by SadDev
|
트랜잭션 거는 문제 때문에 삽질에 삽질 하다가.. 대충이라도 정리..
참고 페이지

#include <stdlib.h>

CDataSource mDataSource;
CSession mSession;

CDBPropSet DBInit(DBPROPSET_DBINIT);
HRESULT hr;
IString Conn;   // IString 은 그냥 CString / char로 만들어서 쓰면 됨.

  hr = CoInitialize(0);
  if(FAILED(hr))
  {
    AfxMessageBox("CoInitialize 실패");
    return false;
  }

  Conn.Format("PROVIDER=SQLOLEDB;SERVER=[ServerIP | ServerName];UID=[Logid ID];PWD=[PassWord];DATABASE=[DBName]");
  DBInit.AddProperty(DBPROP_INIT_PROMPT, (short)4);

  DBInit.AddProperty(DBPROP_INIT_PROVIDERSTRING, Conn.ToChar());
DBInit.AddProperty(DBPROP_INIT_LCID, (long)1043);

  hr = mDataSource.Open(_T("SQLOLEDB"), &DBInit);
  if(FAILED(hr))
  {
    AddMessage(NSS_E_DB_CONN, "Can't Connect Database");
    return false;
  }

  hr = mSession.Open(mDataSource);
  if(FAILED(hr))
  {
    AddMessage(NSS_E_DB_OPEN_SESSION, "Can't Open Session");
    return false;
  }
//==================================================================================================
// 실제 소스에서 위 / 아래는 각각 함수로 만들어져서 따로 분리 되어 있으나.. 설명을 위해 하나의 소스에 적음
//==================================================================================================
        CCommand<CDynamicAccessor, CRowset, CNoMultipleResults> Cmd;
HRESULT hr;
IString SQLComm, UserID;
int iError;
short sCount;

rReadPacketStream.ReadString(UserID);
sCount = rReadPacketStream.ReadShort();
       mSession.StartTransaction(ISOLATIONLEVEL_READCOMMITTED, 0, NULL, NULL);    // StartTransaction 으로 트랜잭션을 건다.

for(int i = 0; i < sCount; i++)
{
IString Name;
rReadPacketStream.ReadString(Name);

try
{
SQLComm.Format2(1024,"EXEC dbo.BB_SET_ADD_DATA '%s'", Name.ToChar());
hr = Cmd.Open(mSession, SQLComm.ToChar());
if(FAILED(hr))
{
iError = NSS_E_SQL_INSERT;
throw "AddPticher : SQL Insert Failed";
}
}
catch(char *cpErr)
{
mSession.Abort(NULL, FALSE, FALSE);  // sCount 만큼 인서트를 진행하다가.. 한번이라도 오류가 나면 Abort 실행(롤백)
if(strlen(cpErr) > 0) AddMessage(iError, cpErr);
Cmd.Close();
return iError;
}
}
mSession.Commit(FALSE, XACTTC_SYNC, 0);  // 전부 정상적으로 실행 되면 Commit
Cmd.Close();

return true;
}


여기서 중요한건 역시나 StartTransaction , Abort , Commit 

프로시져에는 SET XACT_ABORT ON 을 꼭 적어주자..

Posted by SadDev
|
최근 맞고 서버가 동접 100~200에서 갑자기 맥스 1600으로 올랐다.
그로 인해 서버상의 문제가 많이 발생하고 몇가지 수정을 하면서 알게 된 것들을 정리..

1. DB Index는 역시 중요하다..
 - Index를 잘못 걸어 둔 테이블이 있어서 DB부하가 발생하고 있어서 해당 테이블에 Index를 걸어서 수정
 
2. 네트워크 전송 속도를 잘 체크하자
 - 100Mbps 라인에 10Mbps 사용 중인데 1000명정도 되자 네트워크 부하가 좀 걸리는 것다.
 - 네트워크 사용량은 7~8% 가 나왔고 어쨋든... 어플에 따라 다르겠지만 우리 어플에서는 부하가 좀 발생해서 회선 증선으로 해결

3. CPU 부하를 체크하자..
 - 사실 이거 아직 제대로 못잡았다.
 - 평소 CPU 사용량이 10% 미만이지만 1000명이 넘어가면 30%정도까지 간다. 30%가 큰 수치는 아니지만 이때부터 서버가 조금씩 버벅 댄다.
 - 우선 DB서버와 게임서버를 분리해서 운영할 예정
 - 물리적 서버 한대당 게임 서버 약 10개가 떠 있음..

어쨋든 물리적 서버 한대당 1500명정도까지는 받아 들이는데 성공..

Posted by SadDev
|

오랫만에 개발 관련 글을 적는것 같다 ㅡㅡ;;

최근에 GridView의  Pager 를 사용해 보다가. 왠지 custom도 짜증나고해서 간단한 페이징 기능을 구현했다.
아직 좀더 손봐야 되지만 우선 기본적인 부분 까지만 정리한걸 올려본다.

<asp:GridView ID="GVMember" runat="server" AutoGenerateColumns="true"
     onrowdatabound="GVMember_RowDataBound">
    </asp:GridView>
<p></p>
  <asp:Button ID="btnPrev" runat="server" Text="Prev" OnClick="btnPrev_Clicked"  Visible="false" />
 <asp:DropDownList ID="ddlPages" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlPages_SelectedIndexChanged"></asp:DropDownList> / <asp:Label ID="lblTotal" runat="server"></asp:Label>
 <asp:Button ID="btnNext" runat="server" Text="Next" OnClick="btnNext_Clicked"  Visible="false" />

GridView 는 그냥 그대로 놔두고
버튼 (이전 페이지, 다음페이지)와 드롭다운리스트로 페이지 리스트를 넣었다 (페이지 바로가기)


  static int nPage = 1;     // 현재 페이지 번호
  static int iPage = 30;     // 한페이지에 몇개의 게시물을 보여줄지 결정
  static int iTotal = 0;       // 전체 게시물 수
  static int iTotalPage = 1;  // 전체 페이지 수

protected void Page_Load(object sender, EventArgs e)
{
  if(!IsPostBack) ServerDataBind();   // PostBack이 아닐때만  실행
}

public void ServerDataBind()
  {
   conn = db.dbcon("Board");   // DB 커넥션은 개인적으로 함수 만들어서 사용 중

   SqlParameter[] param = new SqlParameter[2];
   param[0] = new SqlParameter("@PAGE", SqlDbType.Int);
   param[1] = new SqlParameter("@TOTAL", SqlDbType.Int);

   param[0].Value = nPage;
   param[1].Direction = ParameterDirection.Output;
   
   ds = SqlHelper.ExecuteDataset(conn, CommandType.StoredProcedure, "dbo.BOARD_GET_LIST", param);   // SQLHelper 사용중

   iTotal = Convert.ToInt32(param[1].Value);

   GVMember.DataSource = ds.Tables[0];
   GVMember.DataBind();
 
   conn.Close();

   iTotalPage = (iTotal / iPage) + 1;   // 전체 페이지 수는 (전체게시물 /페이지당 표시 수) + 1
   SetPaging();
  }

private void SetPaging()
  {
   lblTotal.Text = iTotalPage.ToString();   // 전체 페이지 수를 라펠에 표시
   ddlPages.Items.Clear();  // 드롭다운리스트의 아이템 클리어

   for (int i = 0; i < iTotalPage; i++)
   {
    int tmp = i + 1;
    ListItem li = new ListItem(tmp.ToString());

    if (nPage == tmp) li.Selected = true;    // 현재 페이지 번호와 일치하면 selected
    else li.Selected = false;

    ddlPages.Items.Add(li);
   }

   if (nPage > 1)   // 현재 페이지가 1페이지면 이전 페이지 버튼 안보임
   {
    btnPrev.Visible = true;
    btnPrev.Text = (nPage - 1).ToString();  
   }
   else btnPrev.Visible = false;

   if (nPage < iTotalPage)   // 현재 페이지가 끝페이지면 다음 페이지 버튼 안보임
   {
    btnNext.Visible = true;
    btnNext.Text = (nPage + 1).ToString();
   }
   else btnNext.Visible = false;
  }


protected void GVMember_RowDataBound(object sender, GridViewRowEventArgs e)   // 데이터 바운드 할때 padding 조금 넣어놨음
  {
   for (int i = 0; i < e.Row.Cells.Count; i++)
    e.Row.Cells[i].Style.Add("padding", "5px");   
  }

protected void btnNext_Clicked(object sender, EventArgs e)
  {
    nPage++;
    
    ServerDataBind();
   
  }

  protected void btnPrev_Clicked(object sender, EventArgs e)
  {
   if (nPage > 1)
   {
    nPage--;
    ServerDataBind();
   }
  }

protected void ddlPages_SelectedIndexChanged(object sender, EventArgs e)
  { 
   nPage = ddlPages.SelectedIndex + 1;
   ServerDataBind();
  }


===============================================
프로시져

CREATE PROCEDURE [dbo].[BOARD_GET_LIST]
 @PAGE Int
 ,@TOTAL  Int OUTPUT
AS
BEGIN
 SELECT @TOTAL = COUNT(*) FROM BOARD_TABLE
 
  SELECT * FROM
  (
   SELECT TOP(30) * FROM
   (
    SELECT TOP (@PAGE * 30) * FROM MEMBER ORDER BY RegDate DESC
   ) A ORDER BY A.RegDate ASC
  ) B  ORDER BY B.Regdate DESC 
END
=============================================================

아래와 같은 형식으로 페이지를 표시한다..

전체  994페이지 중 현재 197페이지이며   앞페이지와 다음 페이지 번호를 버튼에 사용 중





이제 1,2,3,4,5,6,7,8,9,10  과 같이 페이지를 표시하는 기능만 추가하면 되는데...
천천히 해야 겠다..
Posted by SadDev
|

1 ~ 100 까지 랜덤하게 숫자를 뽑을때 중복되지 않게 뽑으면서 속도까지 빠르려면 어떤 방법이 있을까??

일반적으로 사실 for문 을 잘 돌리면 중복 되지 않게 뽑는건 어렵지 않다..
다만 중복 for문에 의해 속도가 느려질뿐... 1 ~ 10 정도의 작은 수는 괜찮지만 1000, 10000 같이 숫자가 커질수록 부하는 몇배로 커진다...

우선 한가지 생각해본 방법은
미리 배열에 1 ~100까지 담아두고 하나씩 빼오는 것.
그러다 이미 빠진 숫자가 나오면 그 옆의 숫자를 가져오는 것을 생각해봤다.

IString arrNum[100];
for(int i = 1 i < 101; i++)
{
  arrNum[i] = i+1;
}
for(int i = 1; i < 101; i++)
   {
    sTemp = (short)rand() % 100 ;
    while(arrNum[sTemp].Compare("")==0)
    {
     sTemp++;
     if(sTemp == 100) sTemp = 1;
    }
    arrNum[sTemp] = "";
   }
printf("%d", sTemp);

①②③④⑤⑥⑦⑧⑨⑩....... 이렇게 100까지 저장해 둔다.

랜덤을 돌려서 5가 나오면
①②③④""⑥⑦⑧⑨⑩.......   5는 공백이 된다.

쭉 for문을 돌다가 또 5가 나오면 그 옆 숫자인 6을 가져오고.. 6도 비어있으면 그 옆의 7... 이런식으로 한칸 옆의 숫자를 가져오면서 돌게 된다.


하지만 위 코드도 단점이 있었다..
낮은 확률이긴 하지만 마지막에 가면 근접한 숫자들이 뭉쳐서 나올때가 있다.


그래서 검색을 하고 하고 또 해서 찾아낸 방법.
int sCard = 100;
int *x = new int[sCard];
   for (int j = 0 ; j < sCard; j++)
    x[j] = j;
   
   for (int j = 0; j < sCard; j++)
   {
    int tmp = 0;
    int k = 0;
    int l = 0;
    for(int m = 0; m < 8; m++)
    {
     tmp += rand() << (32 - ((m + 1) * 4));
    }
    k = (tmp % (sCard - j)) + j;
    l = x[j];
    x[j] = x[k];
    x[k] = l;
   }
   free(x);


아참.. 위 코드는 0~ 100이 되겠다..
인덱스 가져올 일이 있어서 0 부터로 짯음...

사실 소스에서
 for(int m = 0; m < 8; m++)
    {
     tmp += rand() << (32 - ((m + 1) * 4));
    }
    k = (tmp % (sCard - j)) + j;


이부분은 이해를 못하고 있다..
먼가 중요한 부분이고 위 소스 때문에 난수가 제대로 나오는것 같은데 아직 정확히 이해는 못하고 있다 ;ㅁ;

'프로그래밍 > C++ / C' 카테고리의 다른 글

[c++] CHttpConnection에서 한글 전송 시 null 문제  (0) 2011.01.13
[C++/C] 트랜잭션 ...  (0) 2010.12.23
Posted by SadDev
|

C#에서 DataGridViewRow 를 복사하려는데 오류가 자꾸 발생한다.

분명 설명에는 DataGridView.Rows.Add(DataGridViewRow )가 있다..
그런데 왜 오류가 날까....

이유는 Row에 값을 넣는 방법이 문제 였다 ㅡㅡ;;

대충 해결 방법

DataGridView dgv = new DataGridView();
...  (dgv에 특정 데이터를 집어 넣은 상태);

DataGridView dGrid  = new DataGridView();
DataGridViewRow dgvRow = new DataGridViewRow();
dgvRow = CloneWithValues(dgv.Rows[i]);

dGrid.Rows.Add(dgvRow); 
public DataGridViewRow CloneWithValues(DataGridViewRow row);
{
      DataGridViewRow clonedRow = (DataGridViewRow)row.Clone();
      for (Int32 index = 0; index < row.Cells.Count; index++)
      {
        clonedRow.Cells[index].Value = row.Cells[index].Value;
      }
      return clonedRow;
}

함수로 만들었지만.. 문제는 Cell에 값을 넣는게 문제 였다..
Row를 만들고 셀에 값을 잘 넣어주면 해결 되더라능 ㅡㅡ;

Posted by SadDev
|

C#에서 MessageBox는 javaScript의 alert 혹은 confirm 과 같다.

우선 MessageBox.Show() 의 사용법은 여러가지가 있지만.. 사실 써본적도 없다.
기본적인 두가지만 쓸뿐 --;;;

그 첫번째 .. alert과 동일한  MessageBox

1. MessageBox.Show("텍스트");

private void button_Click(object sender, EventArgs e)
{
      MessageBox.Show("오류 발생 !!");
}




2. MessageBox.Show(" 내용", "설명", 버튼 종류)

private void button2_Click(object sender, EventArgs e)
{
      if (MessageBox.Show("취소를 누르시면 입력하신 내용이 모두 초기화 됩니다.\r계속 하시겠습니까?", "입력 취소", MessageBoxButtons.YesNo) == DialogResult.Yes)
      {
        this.DialogResult = DialogResult.Abort;
      }
}



간단히 alert과 confirm의 C# 버젼으로 기억하면 된다.


이때 줄바꿈 문자는 \r 을 사용한다.. \n 은 안됨 ;ㅁ;


우선 MessageBoxButtons는 여러가지가 있는데  "Yes"는 예 버튼 "No" 는 아니오 버튼 "OK"는 확인 버튼 등이 있다.  이중 YesNo 는 예 , 아니오 버튼.
그리고 Dialogresult  는 확인 창의 결과 값인데..  Yes 이면 .. 즉 예를눌렀을때... 를 의미한다..

Posted by SadDev
|

ListView 를 써서 DataGridView의 작업을 하려 했던 내가 한심하다 ;ㅁ;
Listview의 Detail 모드에서 데이터를 작업해보려 하니 이게 아니지 싶어서 고민을 해봤다.

그러다 보니.. DataTable이 생각났고 DataTable을 쓰려고 했더니 이넘이 또 WindowForm 에서는 안된다 ㅡㅡ;;

그래서 비슷한 기능을 가진녀석이 있을거라는 생각에 ToolBox를 열심히 뒤져보니 역시나...

DataGridView를 찾아냈다.

사용법은 간단하다.

using System.Windows.Forms;

namespace WindowsFormsApplication1
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
      Init();
    }

    public void Init()
    {
      DataGridView dgrid = new DataGridView();  //  DataGridView 생성
      dgrid.Width = 600;
      dgrid.Height = 300;
      this.Controls.Add(dgrid);   

      dgrid.ColumnCount = 3;    // 컬럼의 수 지정
      dgrid.ColumnHeadersVisible = true;

      dgrid.Columns[0].Name = "ID";   // 컬럼 1의 이름
      dgrid.Columns[1].Name = "Name";   // 컬럼 2의 이름
      dgrid.Columns[2].Name = "Age";   // 컬럼 3의 이름

      dgrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);   // 컬럼의 크기를 자동으로 조절

     // 데이터는 아래처럼 string[] 배열에 담아서 그냥 Rows.Add(string 배열) 해주면 편하다.
      for (int i = 0; i < 5; i++)
      {
        string[] rows = new string[]{i.ToString(), "aaanmjrystyktsyk,ts,dtuk", ((i+1)*10 ).ToString()};
        dgrid.Rows.Add(rows);
      }

    }
  }
}

Posted by SadDev
|