/*

  To my parents
  Eduard Svjatoslavovich and Ludmila Aleksandrovna Barkhatov
  
	(c) Barkhatov Andrej Eduardovich
	
*/

#include "placer.h"

void imp_hist(IplImage **pimg)
{
	int i, hist_size[2] = {255, 255};
	float rg[2] = {0, 256};
	float rg1[2] = {0, 256};
	float *ranges[2], max_val = 0;
	IplImage *img = *pimg, *tmp[3] = {0, 0, 0};
	CvHistogram *hist = 0;
	char buf[100] = {0};
	CvSize img_sz;
	
	ranges[0] = rg;
	ranges[1] = rg1;
	img_sz.width = img->width;
	img_sz.height = img->height;
	hist = cvCreateHist((img->nChannels == 3 ? 2 : 1), hist_size, CV_HIST_ARRAY, ranges, 1);
	for (i = 0; i < img->nChannels; i++)
		tmp[i] = cvCreateImage(img_sz, 8, 1);
	if (img->nChannels == 3)  {
		IplImage *hsv;
		strcpy(buf, "RgbHsv,");
		STATUS_MSG(buf);
		hsv = cvCreateImage(img_sz, 8, 3);
		cvCvtColor(img, hsv, CV_RGB2HSV);
		cvCvtPixToPlane(hsv, tmp[0], tmp[1], tmp[2], 0);
		cvReleaseImage(&hsv);
	}
	else {
		strcpy(buf, "Gray,");
		STATUS_MSG(buf);
		cvCopy(img, tmp[0], 0);
	}
	strcat(buf, "Histo,");
	STATUS_MSG(buf);
	cvCalcArrHist((CvArr **) tmp, hist, 0, 0);
	cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0);
	{
		double s = max_val ? SendDlgItemMessage(hDlg, ID_BTN(HIST) + 2, UDM_GETPOS, 0, 0) / max_val : 0.0;
		cvConvertScale(hist->bins, hist->bins, s, 0);
	}
	strcat(buf, "Proj");
	STATUS_MSG(buf);
	cvCalcArrBackProject(tmp, tmp[0], hist);
	strcat(buf, " *");
	STATUS_MSG(buf);
	if (img->nChannels == 3)
		cvCvtPlaneToPix(tmp[0], tmp[1], tmp[2], 0, img);
	else
		cvCopy(tmp[0], img, 0);
	cvReleaseHist(&hist);
	for (i = 0; i < 3; i++)
		if (tmp[i])
			cvReleaseImage(&tmp[i]);
}

void imp_pyrm(IplImage **pimg)
{
	IplImage *img = *pimg, *tmp = 0;
	CvSeq *seq = 0;
	CvMemStorage *stor = 0;
	int w, h, par = SendDlgItemMessage(hDlg, ID_BTN(PYRM) + 2, UDM_GETPOS, 0, 0);
	char buf[100] = {0};
	CvSize img_sz;
	
	w = img->width;
	h = img->height;
	img_sz.width = img->width;
	img_sz.height = img->height;
	strcpy(buf, "Pyramid");
	STATUS_MSG(buf);
	if (par) {
		tmp = cvCreateImage(img_sz, 8, img->nChannels);
		tmp->width = img->width &= -(1 << 5);
		tmp->height = img->height &= -(1 << 5);
		stor = cvCreateMemStorage(0);
		cvPyrSegmentation(img, tmp, stor, &seq, 5, par, 0);
		cvReleaseImage(pimg);
		*pimg = tmp;
	}
	else {
		img->width &= -2;
		img->height &= -2;
		img_sz.width /= 2;
		img_sz.height /= 2;
		tmp = cvCreateImage(img_sz, 8, img->nChannels);
		cvPyrDown(img, tmp, 7);
		cvPyrUp(tmp, img, 7);
		cvReleaseImage(&tmp);
	}
	(*pimg)->width = w;
	(*pimg)->height = h;
	strcat(buf, " *");
	STATUS_MSG(buf);
	cvReleaseMemStorage(&stor);
}

void imp_fill(IplImage **pimg, POINT *ref)
{
	int lo, up, t, col;
	char buf[100] = {0};
	CvPoint c;
	IplImage *img = *pimg;
	
	c.x = ref->x;
	c.y = ref->y;
	col = RGB(GetDlgItemInt(hDlg, ID_COLOR_B, 0, 0), GetDlgItemInt(hDlg, ID_COLOR_G, 0, 0),GetDlgItemInt(hDlg, ID_COLOR_R, 0, 0));
	t = SendDlgItemMessage(hDlg, ID_BTN(FILL) + 2, UDM_GETPOS, 0, 0);
	lo = img->nChannels == 1 ? t / 4 : t;
	up = img->nChannels == 1 ? 0 : t;
	strcpy(buf, "FloodFill");
	STATUS_MSG(buf);
	cvFloodFill(img, c, col, CV_RGB(lo, lo, lo), CV_RGB(up, up, up), 0, CV_FLOODFILL_FIXED_RANGE, 0);
	strcat(buf, " *");
	STATUS_MSG(buf);
}

void imp_rgbg(IplImage **pimg)
{
	int i;
	IplImage *img = *pimg, *tmp;
	char buf[100] = {0};
	CvSize img_sz;

	if (img->nChannels != 3)
		return;
	img_sz.width = img->width;
	img_sz.height = img->height;
	strcpy(buf, "RgbGray");
	STATUS_MSG(buf);
	tmp = cvCreateImage(img_sz, 8, 1);
	if (!(i = SendDlgItemMessage(hDlg, ID_BTN(RGBG) + 2, UDM_GETPOS, 0, 0)))
		cvCvtColor(img, tmp, CV_RGB2GRAY);
	else if (i == 1)
		cvCvtPixToPlane(img, tmp, 0, 0, 0);
	else if (i == 2)
		cvCvtPixToPlane(img, 0, tmp, 0, 0);
	else if (i == 3)
		cvCvtPixToPlane(img, 0, 0, tmp, 0);
	cvCvtColor(tmp, img, CV_GRAY2RGB);
	strcat(buf, " *");
	STATUS_MSG(buf);
	cvReleaseImage(&tmp);
}

void imp_erod(IplImage **pimg)
{
	IplImage *img = *pimg;
	char buf[100] = {0};
	int f = SendDlgItemMessage(hDlg, ID_BTN(EROD) + 2, UDM_GETPOS, 0, 0);
	
	strcpy(buf, f ? "Erode" : "Dilate");
	STATUS_MSG(buf);
	if (f)
		cvErode(img, img, 0, 1);
	else
		cvDilate(img, img, 0, 1);
	strcat(buf, " *");
	STATUS_MSG(buf);
}

void imp_smoo(IplImage **pimg)
{
	IplImage *img = *pimg;
	char buf[100] = {0};
	int par = 1 + 2 * SendDlgItemMessage(hDlg, ID_BTN(SMOO) + 2, UDM_GETPOS, 0, 0);
	
	strcpy(buf, "Smooth");
	STATUS_MSG(buf);
	cvSmooth(img, img, CV_GAUSSIAN, par, par);
	strcat(buf, " *");
	STATUS_MSG(buf);
}

void imp_cont(IplImage **pimg)
{
	IplImage *img = *pimg, *tmp[3] = {0,0,0};
	CvSize img_sz;
	unsigned char lut[256];
	CvMat* lut_mat;
	char buf[100] = {0};
	int i, contrast = 2 * (SendDlgItemMessage(hDlg, ID_BTN(CONT) + 2, UDM_GETPOS, 0, 0) - 50);
	
	img_sz.width = img->width;
	img_sz.height = img->height;
	strcpy(buf, "Contrast,");
	STATUS_MSG(buf);
	for (i = 0; i < img->nChannels; i++)
		tmp[i] = cvCreateImage(img_sz, 8, 1);
	if (img->nChannels == 3)
		cvCvtPixToPlane(img, tmp[0], tmp[1], tmp[2], 0);
	else
		cvCopy(img, tmp[0], 0);
	lut_mat = cvCreateMatHeader(1, 256, CV_8UC1);
	cvSetData(lut_mat, lut, 0);
	if (!contrast) {
		CvHistogram *hist;
		int hist_size = 256;
		float range_0[] = {0, 256}, *ranges[1], s;
		int high = 0, low = 0;
		
		ranges[0] = range_0;
		hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
		if (img->nChannels == 3) {
			IplImage *tmp0 = cvCreateImage(img_sz, 8, 1);
			cvCvtColor(img, tmp0, CV_RGB2GRAY);
			cvCalcArrHist(&tmp0, hist, 0, 0);
			cvReleaseImage(&tmp0);
		}
		else
			cvCalcArrHist(&tmp[0], hist, 0, 0);
		for (i = 0; i < hist_size; i++) {
			if (cvQueryHistValue_1D(hist, i)) {
				low = i;
				break;
			}
		}
		for (i = hist_size - 1; i >= 0; i--) {
			if (cvQueryHistValue_1D(hist, i)) {
				high = i;
				break;
			}
		}
		strcat(buf, "Hist");
		STATUS_MSG(buf);
		s = 255.0f / (float) (high - low);
		for (i = 0; i < 256; i++) {
			if (i >= low && i <= high)
				lut[i] = (unsigned char)((float)(i - low) * s);
			if (i > high)
				lut[i] = 255;
		}
		cvReleaseHist(&hist);
	}
	else {
		int v;
		double delta, a, b;
		strcat(buf, "Scale");
		STATUS_MSG(buf);
		if (contrast > 0) {
			delta = 127.0 * contrast / 100;
			a = 255.0 / (255.0 - delta * 2);
			b = - a * delta;
		}
		else {
			delta = -128.0 * contrast / 100;
			a = (256.0 - delta * 2) / 255.;
			b = delta;
		}
		for (i = 0; i < 256; i++) {
			v = cvRound(a * i + b);
			if( v < 0 )
				v = 0;
			if( v > 255 )
				v = 255;
			lut[i] = v;
		}
	}
	for (i = 0; i < img->nChannels; i++)
		cvLUT(tmp[i], tmp[i], lut_mat);
	if (img->nChannels == 3)
		cvCvtPlaneToPix(tmp[0], tmp[1], tmp[2], 0, img);
	else
		cvCopy(tmp[0], img, 0);
	strcat(buf, " *");
	STATUS_MSG(buf);
	cvReleaseMat(&lut_mat);
	for (i = 0; i < img->nChannels; i++)
		if (tmp[i])
			cvReleaseImage(&tmp[i]);
}

void imp_thre(IplImage **pimg)
{
	IplImage *img = *pimg;
	char buf[100] = {0};
	int thre = SendDlgItemMessage(hDlg, ID_BTN(THRE) + 2, UDM_GETPOS, 0, 0);
	
	strcpy(buf, "Threshold");
	STATUS_MSG(buf);
	cvThreshold(img, img, thre, 255, CV_THRESH_TRUNC);
	strcat(buf, " *");
	STATUS_MSG(buf);
}

void imp_edge(IplImage **pimg, CvSeq **pseq, IplImage *img_seq)
{
	IplImage *img = *pimg, *tmp;
	char buf[100] = {0};
	CvSize img_sz;
	CvSeq *seq = *pseq;
	int col = RGB(GetDlgItemInt(hDlg, ID_COLOR_R, 0, 0), GetDlgItemInt(hDlg, ID_COLOR_G, 0, 0),GetDlgItemInt(hDlg, ID_COLOR_B, 0, 0));
	
	cvClearSeq(seq);
	cvZero(img_seq);
	img_sz.width = img->width;
	img_sz.height = img->height;
	strcpy(buf, "Canny,");
	STATUS_MSG(buf);
	tmp = cvCreateImage(img_sz, 8, 1);
	if (img->nChannels == 3)
		cvCvtColor(img, tmp, CV_RGB2GRAY);
	else
		cvCopy(img, tmp, 0);
	cvCanny(tmp, tmp, 0, SendDlgItemMessage(hDlg, ID_BTN(EDGE) + 2, UDM_GETPOS, 0, 0), 3);
	strcat(buf, "Contour");
	STATUS_MSG(buf);
	cvFindContours(tmp, seq->storage, pseq, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
	cvDrawContours(img_seq, *pseq, col, 0, 1, 2, 8);
	strcat(buf, " *");
	STATUS_MSG(buf);
	cvReleaseImage(&tmp);
}

void imp_appr(IplImage **pimg, CvSeq **pseq, IplImage *img_seq)
{
	char buf[100] = {0};
	int par = SendDlgItemMessage(hDlg, ID_BTN(APPR) + 2, UDM_GETPOS, 0, 0);
	int col = RGB(GetDlgItemInt(hDlg, ID_COLOR_R, 0, 0), GetDlgItemInt(hDlg, ID_COLOR_G, 0, 0),GetDlgItemInt(hDlg, ID_COLOR_B, 0, 0));
	CvSeq *seq = *pseq, *p0 = 0, *p = 0;
	
	cvZero(img_seq);
	strcpy(buf, "Approx");
	STATUS_MSG(buf);
	while (seq) {
		if (seq->total >= 3) {
			CvSeq *p1 = cvApproxPoly(seq, seq->header_size, (!p ? cvCreateMemStorage(0) : p->storage), CV_POLY_APPROX_DP, par, 0);
			if (p0)
				p0->h_next = p1;
			else
				p = p1;
			p1->h_prev = p0;
			p0 = p1;
		}
		seq = seq->h_next;
	}
	cvDrawContours(img_seq, p, col, 0, 1, 2, 8);
	cvReleaseMemStorage(&(*pseq)->storage);
	*pseq = p;
	strcat(buf, " *");
	STATUS_MSG(buf);
}

void imp_snak(IplImage **pimg, CvSeq **pseq, IplImage *img_seq)
{
	IplImage *img = *pimg, *tmp;
	char buf[100] = {0};
	CvSize img_sz, sz;
	int col = RGB(GetDlgItemInt(hDlg, ID_COLOR_R, 0, 0), GetDlgItemInt(hDlg, ID_COLOR_G, 0, 0),GetDlgItemInt(hDlg, ID_COLOR_B, 0, 0));
	CvSeq *seq = *pseq, *p0 = 0, *p = 0;	
	
	sz.width = sz.height = SendDlgItemMessage(hDlg, ID_BTN(SNAK) + 2, UDM_GETPOS, 0, 0);
	cvZero(img_seq);
	img_sz.width = img->width;
	img_sz.height = img->height;
	strcpy(buf, "Snake");
	STATUS_MSG(buf);
	if (img->nChannels == 3) {
		tmp = cvCreateImage(img_sz, 8, 1);
		cvCvtColor(img, tmp, CV_RGB2GRAY);
	}
	else
		tmp = img;
	while (seq) {
		if (seq->total >= 3) {
			CvSeq *p1 = cvCreateSeq(CV_SEQ_POLYGON, sizeof(CvContour), sizeof(CvPoint), (!p ? cvCreateMemStorage(0) : p->storage));
			{ 
				float alpha = 2, beta = 2, gamma = 2; 
				CvTermCriteria criteria = {CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10, 0.1}; 
				int i; 
				CvPoint *a = cvAlloc(seq->total * sizeof(CvPoint)); 
				for (i = 0; i < seq->total; i++) { 
					CvPoint *pt = (CvPoint *) cvGetSeqElem(seq, i, 0); 
					a[i].x = pt->x; 
					a[i].y = pt->y; 
				} 
				cvSnakeImage(tmp, a, seq->total, &alpha, &beta, &gamma, CV_VALUE, sz, criteria, 0); 
				cvSeqPushMulti(p1, a, seq->total, 0); 
				cvFree(&a); 
			} 
			if (p0)
				p0->h_next = p1;
			else
				p = p1;
			p1->h_prev = p0;
			p0 = p1;
		}
		seq = seq->h_next;
	}
	cvDrawContours(img_seq, p, col, 0, 1, 4, 8);
	cvReleaseMemStorage(&(*pseq)->storage);
	*pseq = p;
	if (img->nChannels == 3)
		cvReleaseImage(&tmp);
	strcat(buf, " *");
	STATUS_MSG(buf);
}

void imp_houg(IplImage **pimg, CvSeq **pseq, IplImage *img_seq)
{
	IplImage *img = *pimg, *tmp;
	CvSize img_sz;
	CvSeq *lines;
	char buf[100] = {0};
	int i, par = SendDlgItemMessage(hDlg, ID_BTN(HOUG) + 2, UDM_GETPOS, 0, 0) + 1;
	int col = RGB(GetDlgItemInt(hDlg, ID_COLOR_R, 0, 0), GetDlgItemInt(hDlg, ID_COLOR_G, 0, 0),GetDlgItemInt(hDlg, ID_COLOR_B, 0, 0));
	CvSeq *seq = *pseq, *p0 = 0, *p = 0;

	cvClearSeq(seq);
	cvZero(img_seq);	
	strcpy(buf, "Hough,");
	STATUS_MSG(buf);
	img_sz.width = img->width;
	img_sz.height = img->height;
	tmp = cvCreateImage(img_sz, 8, 1);
	if (img->nChannels == 3)
		cvCvtColor(img, tmp, CV_RGB2GRAY);
	else
		cvCopy(img, tmp, 0);
	cvCanny(tmp, tmp, 0, 255, 5);
	lines = cvHoughLines2(tmp, seq->storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/360, 70, par, 10);
	sprintf(buf + strlen(buf), "#%d", lines->total);
	STATUS_MSG(buf);
	for (i = 0; i < lines->total; i++) {
		CvPoint *line = (CvPoint*) cvGetSeqElem(lines, i, 0);
		CvSeq *p1 = cvCreateSeq(CV_SEQ_POLYGON, sizeof(CvContour), sizeof(CvPoint), (!p ? cvCreateMemStorage(0) : p->storage));
		cvSeqPush(p1, line);
		cvSeqPush(p1, line + 1);
		if (p0)
			p0->h_next = p1;
		else
			p = p1;
		p1->h_prev = p0;
		p0 = p1;
	}
	cvDrawContours(img_seq, p, col, 0, 1, 2, 8);
	cvReleaseMemStorage(&seq->storage);
	*pseq = p;
	strcat(buf, " *");
	STATUS_MSG(buf);
	cvReleaseImage(&tmp);
}

void imp_cnvx(IplImage **pimg, CvSeq **pseq, IplImage *img_seq)
{
	IplImage *img = *pimg;
	char buf[100] = {0};
	int par = SendDlgItemMessage(hDlg, ID_BTN(CNVX) + 2, UDM_GETPOS, 0, 0);
	CvSeq *seq = *pseq, *p0 = 0, *p = 0;

	cvZero(img_seq);
	strcpy(buf, "Convex");
	STATUS_MSG(buf);
	while (seq) {
		if (seq->total >= 3) {
			CvSeq *p1 = cvConvexHull2(seq, (!p ? cvCreateMemStorage(0) : p->storage), CV_COUNTER_CLOCKWISE, 1);
			if (p0)
				p0->h_next = p1;
			else
				p = p1;
			p1->h_prev = p0;
			p0 = p1;
			{
				CvPoint2D32f center;
				float radius;
				char *b;
				int col;
				cvMinEnclosingCircle(p0, &center, &radius);
				b = img->imageData
					+ max(0, min(img->width - 1, (int) center.x)) * img->nChannels
					+ max(0, min(img->height - 1, (int) center.y)) * img->widthStep;
				col = img->nChannels == 3 ? RGB(*b, *(b + 1), *(b + 2)) : RGB(*b, *b, *b);
				cvDrawContours(img_seq, p0, col, col, 0, CV_FILLED, 8);
			}
		}
		seq = seq->h_next;
	}
	cvReleaseMemStorage(&(*pseq)->storage);
	*pseq = p;
	strcat(buf, " *");
	STATUS_MSG(buf);
}

char pm_path[MAX_PATH];

int macro_load(void)
{
	WIN32_FIND_DATA find;
	HANDLE hfind;
	HWND hlst;
	BROWSEINFO bi;
	IShellFolder *shf = 0;
	char buf[2 * MAX_PATH];
	int ret = 0;
	
	memset(&find, 0, sizeof(WIN32_FIND_DATA));
	memset(&bi, 0, sizeof(BROWSEINFO));
	bi.hwndOwner = hDlg;
	memset(pm_path, 0, MAX_PATH);
	bi.pszDisplayName = pm_path;
	bi.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS | BIF_BROWSEFORCOMPUTER;
	bi.lpszTitle = "Placer Macros Folder";
	if (!GetCurrentDirectoryW(MAX_PATH, (USHORT *) buf)
		|| SHGetDesktopFolder(&shf) != NOERROR
		|| shf->lpVtbl->ParseDisplayName(shf, hDlg, 0, (USHORT *) buf, 0, (LPITEMIDLIST *) &bi.pidlRoot, 0) != NOERROR
		|| !SHGetPathFromIDList(SHBrowseForFolder(&bi), pm_path)
		|| !SetCurrentDirectoryW((USHORT *) buf))
		goto l;
	sprintf(buf, "%s\\*.pm", pm_path);
	hlst = GetDlgItem(hDlg, ID_MLIST);
	ComboBox_ResetContent(hlst);
	if ((hfind = FindFirstFile(buf, &find)) != INVALID_HANDLE_VALUE
		&& find.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
		do ComboBox_AddString(hlst, find.cFileName);
		while (FindNextFile(hfind, &find));
		if (hfind != INVALID_HANDLE_VALUE)
			FindClose(hfind);
		if (!ComboBox_GetCount(hlst))
			goto l;
		ret = 1;
l:
		if (!ret || !pm_path[0]) {
			pm_path[0] = 0;
			STATUS_MSG("Browsing failed.");
		}
		else
			STATUS_MSG("Browsing done.");
		return ret;
}

char *cmd_name[IDL_NUM + IDR_NUM] = {
	"Histo", "Pyram", "Flood", "RgbGr", "Erode", "Smoot", "Contr", "Thres", "Canny", "Appro", "Snake", "Hough", "Convex"
};

int macro_save(CvSeq *cmd_seq)
{
	int i;
	OPENFILENAME ofn;
	char buf[MAX_PATH];
	FILE *f = 0;
	CvSeqReader reader;
	
	if (!cmd_seq->total) {
		STATUS_MSG("Save failed.");
		return 0;
	}
	memset(buf, 0, MAX_PATH);
	memset(&ofn, 0, sizeof(OPENFILENAME));
	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = hDlg;
	ofn.lpstrFile = buf;
	ofn.nMaxFile = MAX_PATH;
	ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER;
	ofn.lpstrFilter = "PlacerMacro\0*.pm\0";
	if (GetSaveFileName(&ofn) && buf[0]) {
		if ((!ofn.nFileExtension || !*(ofn.lpstrFile + ofn.nFileExtension)) && ofn.nFilterIndex)
			strcat(buf, ".pm");
		if (!(f = fopen(buf, "w"))) {
			STATUS_MSG("Save failed.");
			return 0;
		}
		cvStartReadSeq(cmd_seq, &reader, 0);
		for (i = 0; i < cmd_seq->total; i++) {
			CvPoint p;
			CV_READ_SEQ_ELEM(p, reader);
			fprintf(f, "%s\t %d\n", cmd_name[max(0, min((p.x - IDL_FIRST)/3, IDL_NUM + IDR_NUM - 1))], p.y);
		}
		if (f)
			fclose(f);
		STATUS_MSG("Macro Saved.");
		return 1;
	}
	return 0;
}

int macro_sel(void)
{
	FILE *fh = 0;
	int  i, j = -1;
	char *p, buf[MAX_PATH] = {0}, buf0[MAX_PATH] = {0};
	
	ComboBox_GetLBText(GetDlgItem(hDlg, ID_MLIST), ComboBox_GetCurSel(GetDlgItem(hDlg, ID_MLIST)), buf0);
	sprintf(buf, "%s\\%s", pm_path, buf0);
	if (!(fh = fopen(buf, "r"))) {
		STATUS_MSG("Macro Select failed.");
		return 0;
	}
	while (fgets(buf, MAX_PATH, fh)) {
		if (!(p = strtok(buf, "\r\n")) || !(p = strtok(p, " \t")))
			continue;
		for (i = 0; i < IDL_NUM + IDR_NUM; i++)
			if (!strnicmp(p, cmd_name[i], 5))
				break;
			if (i == IDL_NUM + IDR_NUM || !(p = strtok(0, " \t")))
				continue;
			j = atoi(p);
			SendDlgItemMessage(hDlg, ID_UD(i), UDM_SETPOS, 0, (LPARAM) MAKELONG((short) j, 0));
			SendMessage(hDlg, WM_COMMAND, ID_ID(i), 0);
	}
	fclose(fh);
	if (j != -1) {
		STATUS_MSG("Macro Selected.");
		return 1;
	}
	return 0;
}
