⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assocdlg.c

📁 Virtual Floppy Driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
	assocdlg.c

	Virtual Floppy Disk drive control panel
    Copyright (C) 2003 Kenji Kato
*/

#include "sysincl.h"
#include "vfdutil.h"
#include "vfdwin.h"
#include "resource.h"
#include "registry.h"

//
//	Window message handlers
//
static void OnAssocInitDialog(HWND hDlg);
static void OnAssocNew(HWND hDlg, HWND hBtn);
static void OnAssocCheckAll(HWND hDlg, HWND hBtn, int check);
static void OnAssocApply(HWND hDlg, HWND hBtn);
static void OnAssocListNotify(HWND hDlg, LPNMHDR pNMHDR);

//
//	local functions
//
static void UpdateList(HWND hDlg);
static int	AddItem(HWND hList, char *ext, char *prog);
static void ToggleItem(HWND hList, int iItem);

//
//	Add extension dialog
//
static BOOL CALLBACK AddExtProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void OnAddExtEdit(HWND hDlg, HWND hEdit);

//
//	Filetype used for registering file association
//
#define REG_FILETYPE_PREFIX	"VfdWin"

//
//	dialog state variables
//
static int	nCheckedItems = 0;
static int	nChangedItems = 0;
static BOOL	bRegWritable = FALSE;

//
//	window massage dispatcher
//
BOOL CALLBACK AssocProc(
	HWND hDlg,
	UINT msg,
	WPARAM wParam,
	LPARAM lParam) 
{ 
    switch (msg) { 
	case WM_INITDIALOG:
		OnAssocInitDialog(hDlg);
		break;

	case WM_ERASEBKGND:
		// somehow list control is not drawn correctly when this dialog is
		// brought forward if the control has input focus, so force redrawing it
		RedrawWindow(hDlg, NULL, NULL, RDW_INVALIDATE);
		break;

	case WM_COMMAND:
		switch(wParam) {
		case IDC_ASSOC_NEW:
			OnAssocNew(hDlg, (HWND)lParam);
			break;

		case IDC_ASSOC_ALL:
			OnAssocCheckAll(hDlg, (HWND)lParam, 1);
			break;

		case IDC_ASSOC_CLEAR:
			OnAssocCheckAll(hDlg, (HWND)lParam, 0);
			break;

		case IDC_ASSOC_APPLY:
			OnAssocApply(hDlg, (HWND)lParam);
			break;
		}
		break;

	case WM_NOTIFY:
		switch (wParam) {
		case IDC_ASSOC_LIST:
			OnAssocListNotify(hDlg, (LPNMHDR)lParam);
			break;
		}
		break;
    }

    return 0; 
} 

//
//	Association dialog initialize
//
void OnAssocInitDialog(HWND hDlg)
{
	HWND hList;
	HIMAGELIST hImage;
	LVCOLUMN column;
	RECT rect;
	char buf[50];

	//
	//	initialize associatoin list view
	//
	hList = GetDlgItem(hDlg, IDC_ASSOC_LIST);

	if (hList == NULL) {
		DWORD err = GetLastError();

		DEBUG_TRACE1("OnAssocInitDialog : GetDlgItem - %s", ErrMsg(err));

		ShowErrorMessage(err, IDS_ERR_APP_INIT);

		return;
	}

	if (!GetClientRect(hList, &rect)) {
		DWORD err = GetLastError();

		DEBUG_TRACE1("OnAssocInitDialog : GetClientRect - %s", ErrMsg(err));

		ShowErrorMessage(err, IDS_ERR_APP_INIT);

		return;
	}

	//	insert columns 

	memset(&column, 0, sizeof(column));

	column.mask = LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
	column.pszText = buf;

	//	first column -- extension

	if (!LoadString(hAppInstance, IDS_ASSOC_HDR_EXT, buf, sizeof(buf))) {
		DWORD err = GetLastError();

		DEBUG_TRACE1("OnAssocInitDialog : LoadString - %s", ErrMsg(err));

		ShowErrorMessage(err, IDS_ERR_APP_INIT);

		return;
	}

	column.cx = (rect.right - rect.left) / 3;
	column.iSubItem = 0;
	
	if (ListView_InsertColumn(hList, 0, &column) == -1) {
		DWORD err = GetLastError();

		DEBUG_TRACE1( "OnAssocInitDialog : ListView_InsertColumn - %s", ErrMsg(err));

		ShowErrorMessage(err, IDS_ERR_APP_INIT);

		return;
	}


	//	second column -- associated program

	if (!LoadString(hAppInstance, IDS_ASSOC_HDR_PGM, buf, sizeof(buf))) {
		DWORD err = GetLastError();

		DEBUG_TRACE1( "OnAssocInitDialog : LoadString - %s", ErrMsg(err));

		ShowErrorMessage(err, IDS_ERR_APP_INIT);

		return;
	}

	column.cx = column.cx * 2 - GetSystemMetrics(SM_CXVSCROLL);
	column.iSubItem = 1;
	
	if (ListView_InsertColumn(hList, 1, &column) == -1) {
		DWORD err = GetLastError();

		DEBUG_TRACE1( "OnAssocInitDialog : ListView_InsertColumn - %s", ErrMsg(err));

		ShowErrorMessage(err, IDS_ERR_APP_INIT);

		return;
	}

	//	set image list for the list control

	hImage = ImageList_LoadBitmap(
		hAppInstance, MAKEINTRESOURCE(IDB_CHECKBOX), 16, 1, RGB(255, 0, 255));

	if (hImage == NULL) {
		DWORD err = GetLastError();

		DEBUG_TRACE1( "OnAssocInitDialog : ImageList_LoadBitmap - %s", ErrMsg(err));

		ShowErrorMessage(err, IDS_ERR_APP_INIT);

		return;
	}

	SetLastError(ERROR_SUCCESS);

	hImage = ListView_SetImageList(hList, hImage, LVSIL_SMALL);

	if (hImage == NULL && GetLastError() != ERROR_SUCCESS) {
		DWORD err = GetLastError();

		DEBUG_TRACE1("OnAssocInitDialog : ListView_SetImageList - %s", ErrMsg(err));

		ShowErrorMessage(err, IDS_ERR_APP_INIT);

		return;
	}
	
	//	read current association from registry

	UpdateList(hDlg);

	//	set focus on the first item

	ListView_SetItemState(hList, 0,
		LVIS_SELECTED|LVIS_FOCUSED,
		LVIS_SELECTED|LVIS_FOCUSED);

	return;
}

//
//	read current association from registry and put them into list control
//
void UpdateList(HWND hDlg)
{
	HKEY	hKey;
	char	ext[MAX_PATH], prog[MAX_PATH];
	LONG	ret;
	HWND	hList;
	DWORD	index;

	//
	//	Reset list status
	//
	nCheckedItems = 0;
	nChangedItems = 0;

	hList = GetDlgItem(hDlg, IDC_ASSOC_LIST);

	if (hList == NULL) {
		DEBUG_TRACE1("UpdateList : GetDlgItem - %s", ErrMsg(GetLastError()));

		return;
	}

	//
	//	Open registry root key
	//

	ret = RegOpenKeyEx(HKEY_CLASSES_ROOT, NULL, 0, KEY_ALL_ACCESS, &hKey);

	if (ret == ERROR_SUCCESS) {
		bRegWritable = TRUE;
	}
	else {
		//	Failed to open registry in read-write mode

		char msg[MAX_PATH];
		HWND hMsg;

		DEBUG_TRACE1("UpdateList : RegOpenKeyEx(HKCR) - %s", ErrMsg(GetLastError()));

		bRegWritable = FALSE;

		//	Hide controls for manipulating association

		ShowWindow(GetDlgItem(hDlg, IDC_ASSOC_NEW), SW_HIDE);
		ShowWindow(GetDlgItem(hDlg, IDC_ASSOC_ALL), SW_HIDE);
		ShowWindow(GetDlgItem(hDlg, IDC_ASSOC_CLEAR), SW_HIDE);
		ShowWindow(GetDlgItem(hDlg, IDC_ASSOC_APPLY), SW_HIDE);

		//	open registry in read-only mode

		ret = RegOpenKeyEx(HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &hKey);

		if (ret == ERROR_SUCCESS) {
			// succeeded to open read-only

			if (!LoadString(hAppInstance, IDS_ASSOC_CANT_WRITE, msg, sizeof(msg))) {
				DEBUG_TRACE1("UpdateList : LoadString - %s", ErrMsg(GetLastError()));

				// in case LoadString has failed
				strcpy(msg, "Registry is read-only");
			}
		}
		else {
			// failed even to open read-only

			DEBUG_TRACE1(
				"UpdateList : RegOpenKeyEx - %s", ErrMsg(ret));

			EnableWindow(hList, FALSE);

			if (!LoadString(hAppInstance, IDS_ASSOC_CANT_READ, msg, sizeof(msg))) {
				DEBUG_TRACE1(
					"UpdateList : LoadString - %s", ErrMsg(GetLastError()));

				// in case LoadString has failed
				strcpy(msg, "Can't read registry");
			}
		}

		// show why users can't modify association

		hMsg = GetDlgItem(hDlg, IDC_ASSOC_MESSAGE);

		if (hMsg == NULL) {
			DEBUG_TRACE1(
				"UpdateList : GetDlgItem - %s", ErrMsg(GetLastError()));
			return;
		}

		if (!SetWindowText(hMsg, msg)) {
			DEBUG_TRACE1(
				"UpdateList : SetWindowText - %s", ErrMsg(GetLastError()));
			return;
		}

		ShowWindow(hMsg, SW_SHOW);

		if (ret != ERROR_SUCCESS) {

			// cannot even to read registry

			return;
		}
	}

	//
	//	Add common floppy image extensions to list view
	//

	if ((ret = GetAssociatedProgram(".bin", prog)) == ERROR_SUCCESS) {
		AddItem(hList, ".bin", prog);
	}
	else {
		DEBUG_TRACE1(
			"UpdateList : GetAssociatedProgram(\".bin\") - %s", ErrMsg(ret));
	}

	if ((ret = GetAssociatedProgram(".dat", prog)) == ERROR_SUCCESS) {
		AddItem(hList, ".dat", prog);
	}
	else {
		DEBUG_TRACE1(
			"UpdateList : GetAssociatedProgram(\".dat\") - %s", ErrMsg(ret));
	}

	if ((ret = GetAssociatedProgram(".fdd", prog)) == ERROR_SUCCESS) {
		AddItem(hList, ".fdd", prog);
	}
	else {
		DEBUG_TRACE1(
			"UpdateList : GetAssociatedProgram(\".fdd\") - %s", ErrMsg(ret));
	}

	if ((ret = GetAssociatedProgram(".flp", prog)) == ERROR_SUCCESS) {
		AddItem(hList, ".flp", prog);
	}
	else {
		DEBUG_TRACE1(
			"UpdateList : GetAssociatedProgram(\".flp\") - %s", ErrMsg(ret));
	}

	if ((ret = GetAssociatedProgram(".img", prog)) == ERROR_SUCCESS) {
		AddItem(hList, ".img", prog);
	}
	else {
		DEBUG_TRACE1(
			"UpdateList : GetAssociatedProgram(\".img\") - %s", ErrMsg(ret));
	}

	if ((ret = GetAssociatedProgram(".ima", prog)) == ERROR_SUCCESS) {
		AddItem(hList, ".ima", prog);
	}
	else {
		DEBUG_TRACE1(
			"UpdateList : GetAssociatedProgram(\".ima\") - %s", ErrMsg(ret));
	}

	if ((ret = GetAssociatedProgram(".vfd", prog)) == ERROR_SUCCESS) {
		AddItem(hList, ".vfd", prog);
	}
	else {
		DEBUG_TRACE1(
			"UpdateList : GetAssociatedProgram(\".vfd\") - %s", ErrMsg(ret));
	}

	//
	//	Search registry for other extensions associated with VfdWin
	//

	index = 0;

	for (;;) {
		DWORD size = sizeof(ext);

		ret = RegEnumKeyEx(hKey, index++, ext, &size, NULL, NULL, NULL, NULL);

		if (ret != ERROR_SUCCESS) {
			if (ret != ERROR_NO_MORE_ITEMS) {
				DEBUG_TRACE1(
					"UpdateList : RegEnumKeyEx - %s", ErrMsg(ret));
			}
			break;
		}

		if (ext[0] != '.') {
			// not an extension - try next item
			continue;
		}

		ext[size] = '\0';

		if ((ret = GetAssociatedProgram(ext, prog)) == ERROR_SUCCESS) {
			if (strnicmp(prog, VFD_APP_FILENAME, sizeof(VFD_APP_FILENAME) - 1) == 0) {
				AddItem(hList, ext, prog);
			}
		}
		else {
			DEBUG_TRACE2(
				"UpdateList : GetAssociatedProgram(\"%s\") - %s", ext, ret);
		}
	}

	RegCloseKey(hKey);

	// Enable / Disable the "Check All" and "Clear All" button
	// according to the number of checked items

	EnableWindow(GetDlgItem(hDlg, IDC_ASSOC_CLEAR), nCheckedItems);
	EnableWindow(GetDlgItem(hDlg, IDC_ASSOC_ALL), (nCheckedItems < ListView_GetItemCount(hList)));
}

//
//	Insert an item to the list constrol
//
int AddItem(HWND hList, char *ext, char *prog)
{
	LVITEM item;

	memset(&item, 0, sizeof(item));

	//	make sure that extension is in lower case
	{
		char *p = ext;

		while (*p) {
			*p = (char)tolower(*p);
			p++;
		}
	}

	if (*prog == '\0') {
		if (!LoadString(hAppInstance, IDS_ASSOC_NONE, prog, MAX_PATH)) {
			// in case LoadString failed

			DEBUG_TRACE1(
				"AddItem : LoadString - %s", ErrMsg(GetLastError()));

			strcpy(prog, "(none)");
		}
	}

	//	select check status

	if (strnicmp(prog, VFD_APP_FILENAME, sizeof(VFD_APP_FILENAME) - 1) == 0) {
		//	use checked icon
		item.iImage = 1;

		//	use "Virtual FD" if program is "vfdwin.exe"
		strcpy(prog, VFD_APP_NAME);
	}

	//	if registry is read-only, use grayed check icons

	if (!bRegWritable) {
		item.iImage += 2;
	}

	//	store initial icon state in lParam

	item.lParam = item.iImage;

	//	find if extension is already in list
	{
		LVFINDINFO find;

		memset(&find, 0, sizeof(find));
		find.flags = LVFI_STRING;
		find.psz = ext;

		item.iItem = ListView_FindItem(hList, -1, &find);
	}

	//
	//	insert an item or update check status
	//

	if (item.iItem == -1) {

		// add a new item

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -